完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
项目描述
向PCF8591芯片的AN2通道输入一个电压模拟量,经过AD转换后,单片机通过IIC总线读取转换后的数据,并将其量化后实时显示在LCD上。然后将AD转换后的数据写入PCF8591中进行DA转换,并用LED灯的亮度来显示模拟量的大小。 仿真原理图如下 /*------------------------ FileName: DAC.h Function: 头文件 Author: Zhang Kaizhou Date: 2019-6-13 17:12:49 ------------------------*/ #include #include #include #define uchar unsigned char #define uint unsigned int #define FACTOR 0.01953125 // 量化单位(用一个字节来量化表示5V的电压值,共为256个量化等级; FACTOR = 5 / 256) /*IIC总线端口定义*/ ***it SDA = P2^0; ***it SCL = P2^1; /*LCD1602显示模块端口定义*/ ***it lcdrs = P1^0; ***it lcdrw = P1^1; ***it lcden = P1^2; /*IIC总线模块函数声明*/ void initIIC(); void startIIC(); void responseIIC(); void stopIIC(); void writeDataIIC(uchar dat); void readDataIIC(uchar * dat); /*DAC模块函数声明*/ void writeData8591(uchar dat); void readData8591(uchar channel, uchar * dat); /*LCD1602显示模块函数声明*/ void writeCommand(uchar command); void writeDataLCD(uchar dat); void delay(uint xms); void LCDInit(); void display(uchar dat); /*----------------------------------------------------- FileName: main.c Function: ADC IIC Description: 向PCF8591芯片的AN2通道输入一个电压模拟量, 经过AD转换后,单片机通过IIC总线读取转换后的数据, 并将其量化后实时显示在LCD上。 然后将AD转换后的数据写入PCF8591中进行DA转换, 并用LED灯的亮度来显示模拟量的大小。 Author: Zhang Kaizhou Date: 2019-6-13 17:12:40 ------------------------------------------------------*/ #include "DAC.h" void main(){ uchar dat = 0; initIIC(); LCDInit(); while(1){ /*AD转换*/ readData8591(2, &dat); // 读取通道2模拟输入量化后的数据 display(dat); delay(10); /*DA转换*/ writeData8591(dat); delay(10); } } /*向PCF85991写数据*/ void writeData8591(uchar dat){ /*向PCF8591写入地址字节和控制字节*/ startIIC(); writeDataIIC(0x90); // 向IIC总线发送寻址信号(PCF8591器件地址位90H),并声明要进行写操作 responseIIC(); writeDataIIC(0x40); // 向PCF8591写入控制字节(DA允许; AD为4路单端输入; 禁止自动增益) responseIIC(); /*向PCF8591中写入要进行DA转换的数据*/ startIIC(); responseIIC(); writeDataIIC(0x90); responseIIC(); writeDataIIC(dat); responseIIC(); stopIIC(); } /*从PCF8591的channel模拟输入所对应的ADC数据寄存器中读出数据到变量dat*/ void readData8591(uchar channel, uchar * dat){ /*向PCF8591写入地址字节和控制字节*/ startIIC(); writeDataIIC(0x90); // 向IIC总线发送寻址信号(PCF8591器件地址位90H),并声明要进行写操作 responseIIC(); writeDataIIC(0x40 | channel); // 向PCF8591写入控制字节(DA允许; AD为4路单端输入; 禁止自动增益; 选择通道channel) responseIIC(); /*从PCF8591读取数据*/ startIIC(); writeDataIIC(0x91); // 向IIC总线发送寻址信号,并声明要进行读操作 responseIIC(); readDataIIC(dat); stopIIC(); // 注意此处无响应信号,直接关闭IIC总线即可(否则会导致读取的数据不稳定) } /*---------------------------- FileName: IIC.c Function: 实现IIC总线基本操作 Author: Zhang Kaizhou Date: 2019-6-13 17:13:07 ----------------------------*/ #include "DAC.h" /*IIC总线初始化*/ void initIIC(){ SCL = 1; _nop_(); SDA = 1; _nop_(); } /*IIC总线启动信号*/ void startIIC(){ // 在SCL高电平期间,SDA产生一个下降沿表示启动 SDA = 1; _nop_(); SCL = 1; _nop_(); SDA = 0; _nop_(); } /*IIC总线应答信号*/ void responseIIC(){ // 从机在SCL高电平期间将SDA拉低表示应答 SDA = 0; _nop_(); SCL = 1; _nop_(); SCL = 0; _nop_(); } /*IIC总线停止信号*/ void stopIIC(){ // 在SCL高电平期间,SDA产生一个上升沿表示停止 SDA = 0; _nop_(); SCL = 1; _nop_(); SDA = 1; _nop_(); } /*向IIC总线写一个字节数据*/ void writeDataIIC(uchar dat){ uchar i, temp; temp = dat; for(i = 0; i < 8; i++){ temp = temp << 1; SCL = 0; _nop_(); SDA = CY; _nop_(); SCL = 1; _nop_(); } SCL = 0; _nop_(); SDA = 1; _nop_(); } /*从IIC总线读一个字节数据*/ void readDataIIC(uchar * dat){ uchar i; SCL = 0; _nop_(); SDA = 1; _nop_(); for(i = 0; i < 8; i++){ SCL = 1; _nop_(); * dat = ((* dat) << 1) | SDA; SCL = 0; _nop_(); } } /*----------------------------- FileName:display.c Function: LCD1602显示函数 Author: Zhang Kaizhou Date: 2019-6-13 17:12:59 ------------------------------*/ #include "DAC.h" uchar code table0[] = {"ADC"}; uchar code table1[] = {"Voltage:"}; uchar code table2[] = {"0123456789"}; uchar num = 0; /*初始化LCD1602的设置*/ void LCDInit(){ uchar i; lcden = 0; // 拉低使能端,准备产生使能高脉冲信号 writeCommand(0x38); // 显示模式设置(16x2, 5x7点阵,8位数据接口) writeCommand(0x0c); // 开显示,不显示光标 writeCommand(0x06); // 写一个字符后地址指针自动加1 writeCommand(0x01); // 显示清零,数据指针清零 /*LCD上电界面*/ writeCommand(0x80); // 将数据指针定位到第一行首 for(i = 0; i < strlen(table0); i++){ writeDataLCD(table0); delay(5); } writeCommand(0x80 + 0x40); // 将数据指针定位到第二行首 for(i = 0; i < strlen(table1); i++){ writeDataLCD(table1); delay(5); } } /*LCD显示函数*/ void display(uchar dat){ /*数据的量化*/ float temp = FACTOR * dat; uchar i, j; if(dat == 255){ i = 5; j = 0; }else{ // 分离整数和小数部分 i = (uchar)temp; j = (temp - i) * 10; } /*数据显示*/ writeCommand(0x80 + 0x40 + strlen(table1)); writeDataLCD(table2); delay(5); writeCommand(0x80 + 0x40 + strlen(table1) + 1); writeDataLCD('.'); delay(5); writeCommand(0x80 + 0x40 + strlen(table1) + 2); writeDataLCD(table2[j]); delay(5); } /*写指令函数*/ void writeCommand(uchar command){ lcdrs = 0; // 命令选择 lcdrw = 0; P0 = command; delay(5); lcden = 1; // 产生一个正脉冲使能信号 delay(5); lcden = 0; } /*写数据函数*/ void writeDataLCD(uchar dat){ lcdrs = 1; // 数据选择 lcdrw = 0; P0 = dat; delay(5); lcden = 1; delay(5); lcden = 0; } /*延时xms函数*/ void delay(uint xms){ uint i, j; for(i = xms; i > 0; i--) for(j = 110; j > 0; j--); } |
|
|
|
只有小组成员才能发言,加入小组>>
3310 浏览 9 评论
2991 浏览 16 评论
3492 浏览 1 评论
9057 浏览 16 评论
4086 浏览 18 评论
1175浏览 3评论
603浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
596浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2333浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1894浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 15:34 , Processed in 1.169181 second(s), Total 79, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号