找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2436|回复: 2
收起左侧

简单的发一个51单片机的LCD1602的AD转换代码(可以直接复制的)

[复制链接]
ID:586975 发表于 2019-7-19 16:41 | 显示全部楼层 |阅读模式
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. sbit SDA=P2^0;                   // 将p1.2口模拟数据口
  4. sbit SCL=P2^1;                   // 将p1.7口模拟时钟口
  5. sbit DS1302 =P2^4;
  6. sbit DU = P2^0;
  7. sbit WE = P2^1;
  8. #define uchar unsigned char
  9. #define uint  unsigned int
  10. #define disdata  P0              //显示数据码输出口
  11. sbit LCD_RS = P1^0;            
  12. sbit LCD_RW = P1^1;
  13. sbit LCD_EN = P2^5;
  14. uint data dis[4]={0x00,0x00,0x00,0x00};
  15.                           //定义3个显示数据单元和1个数据存储单元
  16. uchar code dis4[] = {"1- .  V  2- .  V"};
  17. uchar code dis5[] = {"3- .  V  4- .  V"};

  18. #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
  19.                   
  20. bit   bdata SystemError;                //从机错误标志位
  21. /*********************** PCF8591专用变量定义 ***********************/
  22. #define PCF8591_WRITE 0x90
  23. #define PCF8591_READ  0x91
  24. #define  NUM  4              //接收和发送缓存区的深度
  25. uchar idata receivebuf[NUM];    //数据接收缓冲区
  26. void cmg88()//关数码管,点阵函数
  27. {
  28. DU=1;  
  29. P0=0X00;
  30. DU=0;
  31. }
  32. /*******************************************************************/
  33. /*                                                                 */
  34. /*  延时函数                                                       */
  35. /*                                                                 */
  36. /*******************************************************************/
  37. void delay(int ms)
  38. {
  39.     while(ms--)
  40. {
  41.       uchar i;
  42.    for(i=0;i<250;i++)  
  43.     {
  44.      _nop_();      
  45.   _nop_();
  46.   _nop_();
  47.   _nop_();
  48.     }
  49. }
  50. }  
  51. /*******************************************************************/
  52. /*                                                                 */
  53. /*检查LCD忙状态                                                    */
  54. /*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。      */
  55. /*                                                                 */
  56. /*******************************************************************/
  57. bit lcd_busy()
  58. {                          
  59.     bit result;
  60.     LCD_RS = 0;
  61.     LCD_RW = 1;
  62.     LCD_EN = 1;
  63.     delayNOP();
  64.     result = (bit)(P0&0x80);
  65.     LCD_EN = 0;
  66.     return(result);
  67. }
  68. /*******************************************************************/
  69. /*                                                                 */
  70. /*写指令数据到LCD                                                  */
  71. /*RS=L,RW=L,E=高脉冲,D0-D7=指令码。                             */
  72. /*                                                                 */
  73. /*******************************************************************/
  74. void lcd_wcmd(uchar cmd)
  75. {                          
  76.    while(lcd_busy());
  77.     LCD_RS = 0;
  78.     LCD_RW = 0;
  79.     LCD_EN = 0;
  80.     _nop_();
  81.     _nop_();
  82.     P0 = cmd;
  83.     delayNOP();
  84.     LCD_EN = 1;
  85.     delayNOP();
  86.     LCD_EN = 0;  
  87. }
  88. /*******************************************************************/
  89. /*                                                                 */
  90. /*写显示数据到LCD                                                  */
  91. /*RS=H,RW=L,E=高脉冲,D0-D7=数据。                               */
  92. /*                                                                 */
  93. /*******************************************************************/
  94. void lcd_wdat(uchar dat)
  95. {                          
  96.    while(lcd_busy());
  97.     LCD_RS = 1;
  98.     LCD_RW = 0;
  99.     LCD_EN = 0;
  100.     P0 = dat;
  101.     delayNOP();
  102.     LCD_EN = 1;
  103.     delayNOP();
  104.     LCD_EN = 0;
  105. }
  106. /*******************************************************************/
  107. /*                                                                 */
  108. /*  LCD初始化设定                                                  */
  109. /*                                                                 */
  110. /*******************************************************************/
  111. void lcd_init()
  112. {
  113.     delay(15);                  
  114.     lcd_wcmd(0x38);      //16*2显示,5*7点阵,8位数据
  115.     delay(5);
  116.     lcd_wcmd(0x38);         
  117.     delay(5);
  118.     lcd_wcmd(0x38);         
  119.     delay(5);
  120.     lcd_wcmd(0x0c);      //显示开,关光标
  121.     delay(5);
  122.     lcd_wcmd(0x06);      //移动光标
  123.     delay(5);
  124.     lcd_wcmd(0x01);      //清除LCD的显示内容
  125.     delay(5);
  126. }
  127. /*******************************************************************/
  128. /*                                                                 */
  129. /*  设定显示位置                                                   */
  130. /*                                                                 */
  131. /*******************************************************************/
  132. void lcd_pos(uchar pos)
  133. {                          
  134.   lcd_wcmd(pos | 0x80);  //数据指针=80+地址变量
  135. }
  136. /******************************************************************/
  137. /*                                                                */
  138. /* 数据处理与显示                                                 */
  139. /* 将采集到的数据进行16进制转换为ASCLL码。                        */
  140. /*                                                                */
  141. /******************************************************************/
  142. show_value(uchar ad_data)
  143. {   
  144.     dis[2]=ad_data/51;   //AD值转换为3为BCD码,最大为5.00V。
  145.     dis[2]=dis[2]+0x30;  //转换为ACSII码
  146.     dis[3]=ad_data%51;   //余数暂存
  147.     dis[3]=dis[3]*10;    //计算小数第一位
  148.     dis[1]=dis[3]/51;
  149.     dis[1]=dis[1]+0x30;  //转换为ACSII码
  150.     dis[3]=dis[3]%51;
  151.     dis[3]=dis[3]*10;    //计算小数第二位
  152.     dis[0]=dis[3]/51;                                                                             //
  153.     dis[0]=dis[0]+0x30;  //转换为ACSII码           
  154. }
  155. //-------------------------------------------------------------------
  156. // 函数名称: iic_start()
  157. // 函数功能: 启动I2C总线子程序
  158. //-------------------------------------------------------------------
  159. void iic_start(void)
  160. { //时钟保持高,数据线从高到低一次跳变,I2C通信开始
  161. SDA = 1;     
  162. SCL = 1;
  163. delayNOP();      // 延时5us
  164.     SDA = 0;
  165. delayNOP();
  166.     SCL = 0;
  167. }
  168. //-------------------------------------------------------------------
  169. // 函数名称: iic_stop()
  170. // 函数功能: 停止I2C总线数据传送子程序
  171. //-------------------------------------------------------------------
  172. void iic_stop(void)
  173. {   
  174. SDA = 0;       //时钟保持高,数据线从低到高一次跳变,I2C通信停止
  175. SCL = 1;
  176. delayNOP();
  177. SDA = 1;
  178. delayNOP();
  179.     SCL = 0;
  180. }
  181. //------------------------------------------------------------------
  182. // 函数名称: iicInit_()
  183. // 函数功能: 初始化I2C总线子程序
  184. //------------------------------------------------------------------
  185. void iicInit(void)
  186.    {
  187.    SCL = 0;
  188.    iic_stop();
  189.    }  
  190. //-------------------------------------------------------------------
  191. // 函数名称: slave_ACK
  192. // 函数功能: 从机发送应答位子程序
  193. //-------------------------------------------------------------------
  194. void slave_ACK(void)
  195. {
  196. SDA = 0;  
  197. SCL = 1;
  198. delayNOP();
  199. SCL = 0;
  200. }
  201. //-------------------------------------------------------------------
  202. // 函数名称: slave_NOACK
  203. // 函数功能: 从机发送非应答位子程序,迫使数据传输过程结束
  204. //-------------------------------------------------------------------
  205. void slave_NOACK(void)
  206. {
  207. SDA = 1;
  208. SCL = 1;
  209. delayNOP();
  210. SDA = 0;
  211.     SCL = 0;  
  212. }
  213. //-------------------------------------------------------------------
  214. // 函数名称: check_ACK
  215. // 函数功能: 主机应答位检查子程序,迫使数据传输过程结束
  216. //-------------------------------------------------------------------
  217. void check_ACK(void)
  218. {      
  219.     SDA = 1;        // 将SDA设置成输入,必须先向端口写1
  220. SCL = 1;
  221. F0 = 0;
  222. delayNOP();   
  223. if(SDA == 1)    // 若SDA=1表明非应答,置位非应答标志F0
  224.     F0 = 1;
  225.     SCL = 0;
  226. }
  227. //-------------------------------------------------------------------
  228. // 函数名称: IICSendByte
  229. // 入口参数: ch
  230. // 函数功能: 发送一个字节
  231. //-------------------------------------------------------------------
  232. void IICSendByte(uchar ch)

  233. {
  234.    unsigned char idata n=8;     // 向SDA上发送一位数据字节,共八位
  235. while(n--)
  236. {
  237. if((ch&0x80) == 0x80)    // 若要发送的数据最高位为1则发送位1
  238.     {
  239.     SDA = 1;    // 传送位1
  240.    SCL = 1;
  241.       delayNOP();
  242.   // SDA = 0;
  243.    SCL = 0;
  244.     }
  245.   else
  246.   {  
  247.    SDA = 0;    // 否则传送位0
  248.    SCL = 1;
  249.    delayNOP();
  250.      SCL = 0;
  251.   }
  252.   ch = ch<<1;    // 数据左移一位
  253. }
  254. }
  255. //-------------------------------------------------------------------
  256. // 函数名称: IICreceiveByte
  257. // 返回接收的数据
  258. // 函数功能: 接收一字节子程序
  259. //-------------------------------------------------------------------
  260. uchar IICreceiveByte(void)
  261. {
  262. uchar idata n=8;     // 从SDA线上读取一上数据字节,共八位
  263. uchar tdata=0;
  264. while(n--)
  265. {
  266.     SDA = 1;
  267.     SCL = 1;
  268.     tdata =tdata<<1;      //左移一位
  269.      if(SDA == 1)
  270.     tdata = tdata|0x01;   // 若接收到的位为1,则数据的最后一位置1
  271.   else
  272.     tdata = tdata&0xfe;   // 否则数据的最后一位置0
  273.     SCL = 0;
  274.   }
  275.   return(tdata);
  276. }
  277. //-------------------------------------------------------------------
  278. // 函数名称: DAC_PCF8591
  279. // 入口参数: slave_add从机地址,n要发送的数据个数
  280. // 函数功能: 发送n位数据子程序
  281. //-------------------------------------------------------------------
  282. void DAC_PCF8591(uchar controlbyte,uchar w_data)
  283. {   

  284. iic_start();                    // 启动I2C
  285. delayNOP();
  286. IICSendByte(PCF8591_WRITE);     // 发送地址位
  287. check_ACK();                    // 检查应答位
  288.     if(F0 == 1)
  289.   {
  290.   SystemError = 1;
  291.   return;                     // 若非应答,置错误标志位
  292.      }
  293.     IICSendByte(controlbyte&0x77); //Control byte
  294. check_ACK();                    //检查应答位
  295.     if(F0 == 1)
  296.   {
  297.   SystemError = 1;
  298.   return;                    // 若非应答,置错误标志位
  299.   }
  300.     IICSendByte(w_data);        //data byte
  301. check_ACK();                  // 检查应答位
  302.     if(F0 == 1)
  303.   {
  304.   SystemError = 1;
  305.      return;   // 若非应答表明器件错误或已坏,置错误标志位SystemError
  306.   }
  307. iic_stop();         // 全部发完则停止
  308. delayNOP();
  309. delayNOP();
  310. delayNOP();
  311. delayNOP();
  312. }
  313. //-------------------------------------------------------------------
  314. // 函数名称: ADC_PCF8591
  315. // 入口参数: controlbyte控制字
  316. // 函数功能: 连续读入4路通道的A/D转换结果到receivebuf
  317. //-------------------------------------------------------------------
  318. void ADC_PCF8591(uchar controlbyte)
  319. {
  320.     uchar idata receive_da,i=0;
  321. iic_start();
  322. IICSendByte(PCF8591_WRITE); //控制字
  323. check_ACK();
  324. if(F0 == 1)
  325. {
  326.   SystemError = 1;
  327.   return;
  328. }
  329. IICSendByte(controlbyte); //控制字
  330. check_ACK();
  331. if(F0 == 1)
  332. {
  333.   SystemError = 1;
  334.   return;
  335. }
  336.     iic_start();                //重新发送开始命令
  337.     IICSendByte(PCF8591_READ); //控制字
  338. check_ACK();
  339. if(F0 == 1)
  340. {
  341.   SystemError = 1;
  342.   return;
  343. }
  344.   
  345.     IICreceiveByte();   //空读一次,调整读顺序
  346.     slave_ACK();        //收到一个字节后发送一个应答位
  347. while(i<4)
  348. {  
  349.    receive_da=IICreceiveByte();
  350.    receivebuf[i++]=receive_da;
  351.    slave_ACK();       //收到一个字节后发送一个应答位
  352. }
  353. slave_NOACK();       //收到最后一个字节后发送一个非应答位
  354. iic_stop();
  355. }
  356. //-------------------------------------------------------------------
  357. // 函数名称: main
  358. // 函数功能: 主程序
  359. //-------------------------------------------------------------------
  360. main()
  361. {
  362.     uchar i,l;
  363.     delay(10);                 //延时
  364. cmg88();//关数码管,点阵函数
  365. DS1302 =0;
  366.     lcd_init();                //初始化LCD            
  367.         
  368.     lcd_pos(0);                //设置显示位置为第一行的第1个字符
  369.      i = 0;
  370.     while(dis4[i] != '\0')
  371.      {                         //显示字符
  372.        lcd_wdat(dis4[i]);
  373.        i++;
  374.      }
  375.     lcd_pos(0x40);             //设置显示位置为第二行第1个字符
  376.      i = 0;
  377.     while(dis5[i] != '\0')
  378.      {
  379.        lcd_wdat(dis5[i]);      //显示字符
  380.        i++;
  381.      }

  382.   while(1)
  383.   {
  384. iicInit();               //I2C总线初始化
  385.     ADC_PCF8591(0x04);
  386. if(SystemError == 1)   //有错误,重新来
  387.    {
  388.     iicInit();      //I2C总线初始化
  389.      ADC_PCF8591(0x04);
  390.     }   

  391. for(l=0;l<4;l++)
  392.   {
  393.    show_value(receivebuf[0]); //显示通道0      
  394.      lcd_pos(0x02);            
  395.         lcd_wdat(dis[2]);        //整数位显示
  396.         lcd_pos(0x04);            
  397.         lcd_wdat(dis[1]);        //第一位小数显示
  398.         lcd_pos(0x05);            
  399.         lcd_wdat(dis[0]);        //第二位小数显示
  400.       show_value(receivebuf[1]); //显示通道1  
  401.      lcd_pos(0x0b);            
  402.         lcd_wdat(dis[2]);        //整数位显示
  403.         lcd_pos(0x0d);            
  404.         lcd_wdat(dis[1]);        //第一位小数显示
  405.         lcd_pos(0x0e);            
  406.         lcd_wdat(dis[0]);        //第二位小数显示
  407.    show_value(receivebuf[2]); //显示通道2           
  408.      lcd_pos(0x42);            
  409.         lcd_wdat(dis[2]);        //整数位显示
  410.         lcd_pos(0x44);            
  411.         lcd_wdat(dis[1]);        //第一位小数显示
  412.         lcd_pos(0x45);            
  413.         lcd_wdat(dis[0]);        //第二位小数显示
  414.       show_value(receivebuf[3]); //显示通道3  
  415.      lcd_pos(0x4b);            
  416.         lcd_wdat(dis[2]);        //整数位显示
  417.         lcd_pos(0x4d);              
  418.         lcd_wdat(dis[1]);        //第一位小数显示
  419.         lcd_pos(0x4e);            
  420.         lcd_wdat(dis[0]);        //第二位小数显示
  421.    iicInit();               //I2C总线初始化  
  422.       DAC_PCF8591(0x40,receivebuf[0]); //D/A输出
  423.      if(SystemError == 1)   //有错误,重新来
  424.      {
  425.      iicInit();      //I2C总线初始化
  426.    DAC_PCF8591(0x40,receivebuf[0]); //D/A输出
  427.      }         
  428.       //delay(50);                       //延时
  429.   }
  430.    }
  431. }
复制代码
回复

使用道具 举报

ID:198286 发表于 2019-7-30 12:15 | 显示全部楼层
我现在要做的是IIC接口的1602,不知道咋搞
回复

使用道具 举报

ID:586975 发表于 2019-8-2 10:23 | 显示全部楼层
zxy2266 发表于 2019-7-30 12:15
我现在要做的是IIC接口的1602,不知道咋搞

主要先了解一下IIc协议.我还有这方面的帖子还没审核.审核完了你可以看一下.有帮助的话就好.本人也在做一些东西.现在空闲不多.抱歉
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表