找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2692|回复: 0
收起左侧

温度变送器单片机程序LCD1602一排黑格 求助

[复制链接]
ID:314192 发表于 2018-6-18 17:28 | 显示全部楼层 |阅读模式
设计的ads1146热电偶温度变送器,程序烧写进去屏幕出现一排黑格,经检查屏幕与单片机均无损坏。求助程序及电路图如下,感谢各位。
电路原理图如下:
新建文本文档 (6).jpg
程序部分:
  1. /*
  2. 引脚定义:1-VSS 2-VDD 3-V0 4-RS 5-R/W 6-E 7-14 DB0-DB7 15-BLA 16-BLK
  3. ------------------------------------------------*/


  4. #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
  5. #include<intrins.h>

  6. #define RS_CLR RS=0
  7. #define RS_SET RS=1

  8. #define RW_CLR RW=0
  9. #define RW_SET RW=1

  10. #define EN_CLR EN=0
  11. #define EN_SET EN=1

  12. #define DataPort P0

  13. #define uchar unsigned char
  14. #define nop _nop_()

  15. uchar ADC_H;
  16. uchar ADC_L;
  17. uchar ad_result;
  18. uchar bdata ADC;
  19. uchar Read_AD;
  20. uchar sw_sign = 0;
  21. uchar outdata= 0x0000;
  22. xdata unsigned long time_20ms=0;
  23. sbit RS = P1^0;   //定义LCD端口
  24. sbit RW = P1^1;
  25. sbit EN = P1^2;
  26. sbit DU = P2^0;
  27. sbit WE = P2^1;  //显示端口完毕



  28. sbit ADC_SCLK=P2^0;                // 定义ADS1146端口
  29. sbit ADC_DIN=P2^1;
  30. sbit DAC_DOUT=P2^2;
  31. sbit ADC_DRDY=P2^3;
  32. sbit ADC_CS=P2^4;
  33. sbit ADC_START=P3^7;
  34. sbit ADC_REST=P3^6;

  35. sbit ADC_X=ADC^0;          //  ADS1146端口完毕

  36. sbit AD420_LATCH=P3^3;         //定义AD420端口
  37. sbit AD420_CLK=P3^4;
  38. sbit AD420_DATA=P3^5;
  39. sbit AD420_CLEAR=P3^2;        //AD420端口完毕

  40. sbit sw1 = P2^5;//K开关端口定义
  41. sbit sw2 = P2^6;
  42. sbit sw3 = P2^7;

  43. //K型热电偶分度表
  44. static const unsigned int fendubiao_K[29]={0,1697,3435,5136,6812,8504,10230,11981,13741,15509,17302,19086,20863,22647,24407,26158,27892,29593,31277,32944,34578,36204,37787,39354,40896,42404,43878,45940,47000};//Vref=2.5V
  45. //static const unsigned int fendubiao_K[29]={0,1697,3435,5136,6812,8504,10230,11981,13741,15509,17302,19086,20863,22647,24407,26158,27892,29593,31277,32944,34578,36204,37787,39354,40896,42404,43878,45940,47000};//Vref=2.5V

  46. //S型热电偶分度表
  47. static const unsigned int fendubiao_S[177]={0,186,379,580,788,1003,1224,1452,1685,1924,2167,2416,2669,2927,3188,3454,3724,3996,4272,4552,4835,5120,5408,5698,5991,6287,6584,6884,7186,7489,7795,8102,8411,8722,9034,9348,9663,9979,10297,10616,10937,11258,11581,11905,12230,12557,12884,13213,13542,13873,14205,14537,14871,15206,15542,15879,16217,16555,16895,17236,17578,17921,18265,18610,18957,19304,19652,20001,20352,20703,21056,21410,21765,22121,22478,22836,23196,23557,23919,24282,24646,25011,25378,25745,26114,26484,26855,27227,27601,27975,28351,28728,29106,29485,29865,30246,30629,31012,31397,31782,32169,32557,32945,33335,33726,34118,34511,34905,35300,35696,36093,36490,36889,37288,37688,38088,38489,38891,39293,39696,40099,40503,40908,41312,41717,42123,42529,42935,43341,43748,44155,44562,44969,45376,45783,46190,46598,47005,47412,47819,48226,48633,49040,49446,49853,50259,50665,51070,51475,51879,52284,52687,53090,53493,53895,54296,54697,55097,55497,55896,56294,56691,57087,57483,57878,58272,58665,59056,59447,59835,60221,60604,60982,61356,61724,62087,62442};//Vref=2.5V         

  48. void cmg88(void);                 //关数码管,点阵函数
  49. void DelayUs2x(unsigned char t);
  50. void DelayMs(unsigned char t);
  51. void dms(unsigned int t);
  52. void Init_Timer0(void); //定时器函数
  53. bit LCD_Check_Busy(void);   //LCD判忙函数
  54. void LCD_Write_Com(unsigned char com);//LCD写入命令函数
  55. void LCD_Write_Data(unsigned char Data);//LCD写入数据函数
  56. void LCD_Clear(void);//LCD清屏函数
  57. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s);          //LCD写入字符串函数
  58. void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data);    //LCD写入字符函数
  59. void LCD_Init(void); //LCD初始化函数
  60. void AD_init(void);//AD初始化,寄存器设置
  61. void D_OUT(void);//AD读数据
  62. void MaOut(unsigned int out_data);//AD420输出
  63. float K_table(void);//K型热热电势转换成温度
  64. float S_table(void);//K型热热电势转换成温度
  65. /*------------------------------------------------
  66.                     主函数
  67. ------------------------------------------------*/

  68. void main(void)
  69. {
  70. cmg88();//关数码管,点阵函数
  71. LCD_Init();
  72. LCD_Clear();//清屏
  73. /*while (1)
  74. {  
  75.   LCD_Write_Char(7,0,'o');
  76.   LCD_Write_Char(8,0,'k');
  77.   LCD_Write_String(1,1,"Hard Work");
  78.   while(1);
  79. }         */

  80. //init();
  81. AD_init();
  82. while(1)
  83. {
  84. if(sw1 == 0xff){sw_sign = 0;}
  85. if(sw2 == 0xff){sw_sign = 1;}
  86. if(sw3 == 0xff){sw_sign = 2;}

  87. ADC_START=1;
  88.    if(Read_AD==1)
  89.     {
  90.           Read_AD=0;
  91.       D_OUT();
  92.       LCD_Write_String(0,0,"temp");
  93.       if(sw_sign == 0){
  94.       K_table();
  95.       LCD_Write_Data(ad_result);
  96.           outdata = 0x0000;
  97.           outdata = outdata + (ad_result-20);
  98.           MaOut(outdata);
  99.           LCD_Write_String(0,1,"elec");
  100.           LCD_Write_Data(outdata);
  101.       ADC_H=0xff;
  102.       ADC_L=0xff;}
  103.       else
  104.           {
  105.           S_table();
  106.           LCD_Write_Data(ad_result);
  107.           outdata = 0x0000;
  108.           outdata = outdata + (ad_result-20);
  109.           LCD_Write_String(0,1,"elec");
  110.           LCD_Write_Data(outdata);
  111.       ADC_H=0xff;
  112.       ADC_L=0xff;
  113.           }
  114.            

  115. }
  116. //Display();
  117. }
  118. }




  119. void cmg88()//关数码管,点阵函数
  120. {
  121. DU=1;  
  122. P0=0X00;
  123. DU=0;
  124. }
  125. /*------------------------------------------------
  126. uS延时函数,含有输入参数 unsigned char t,无返回值
  127. unsigned char 是定义无符号字符变量,其值的范围是
  128. 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
  129. 长度如下 T=tx2+5 uS
  130. ------------------------------------------------*/
  131. void DelayUs2x(unsigned char t)
  132. {   
  133. while(--t);
  134. }
  135. /*------------------------------------------------
  136. mS延时函数,含有输入参数 unsigned char t,无返回值
  137. unsigned char 是定义无符号字符变量,其值的范围是
  138. 0~255 这里使用晶振12M,精确延时请使用汇编
  139. ------------------------------------------------*/
  140. void DelayMs(unsigned char t)
  141. {

  142. while(t--)
  143. {
  144.      //大致延时1mS
  145.      DelayUs2x(245);
  146.          DelayUs2x(245);
  147. }
  148. }

  149. void dms(unsigned int t)
  150. {
  151. unsigned int i;
  152. while(t--)
  153. {
  154. for(i=0;i<125;i++);
  155. }
  156. }

  157. /*------------------------------------------------
  158.               判忙函数
  159. ------------------------------------------------*/
  160. bit LCD_Check_Busy(void)
  161. {
  162. DataPort= 0xFF;
  163. RS_CLR;
  164. RW_SET;
  165. EN_CLR;
  166. _nop_();
  167. EN_SET;
  168. return (bit)(DataPort & 0x80);
  169. }
  170. /*------------------------------------------------
  171.               写入命令函数
  172. ------------------------------------------------*/
  173. void LCD_Write_Com(unsigned char com)
  174. {  
  175. while(LCD_Check_Busy()); //忙则等待
  176. RS_CLR;
  177. RW_CLR;
  178. EN_SET;
  179. DataPort= com;
  180. _nop_();
  181. EN_CLR;
  182. }
  183. /*------------------------------------------------
  184.               写入数据函数
  185. ------------------------------------------------*/
  186. void LCD_Write_Data(unsigned char Data)
  187. {
  188. while(LCD_Check_Busy()); //忙则等待
  189. RS_SET;
  190. RW_CLR;
  191. EN_SET;
  192. DataPort= Data;
  193. _nop_();
  194. EN_CLR;
  195. }

  196. /*------------------------------------------------
  197.                 清屏函数
  198. ------------------------------------------------*/
  199. void LCD_Clear(void)
  200. {
  201. LCD_Write_Com(0x01);
  202. DelayMs(5);
  203. }
  204. /*------------------------------------------------
  205.               写入字符串函数
  206. ------------------------------------------------*/
  207. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
  208. {     
  209. if (y == 0)
  210.          {     
  211.          LCD_Write_Com(0x80 + x);     //表示第一行
  212.          }
  213. else
  214.          {      
  215.          LCD_Write_Com(0xC0 + x);      //表示第二行
  216.          }        
  217. while (*s)
  218.          {     
  219. LCD_Write_Data( *s);     
  220. s ++;     
  221.          }
  222. }
  223. /*------------------------------------------------
  224.               写入字符函数
  225. ------------------------------------------------*/
  226. void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
  227. {     
  228. if (y == 0)
  229.          {     
  230.          LCD_Write_Com(0x80 + x);     
  231.          }   
  232. else
  233.          {     
  234.          LCD_Write_Com(0xC0 + x);     
  235.          }        
  236. LCD_Write_Data( Data);  
  237. }
  238. /*------------------------------------------------
  239.               初始化函数
  240. ------------------------------------------------*/
  241. void LCD_Init(void)
  242. {
  243.    LCD_Write_Com(0x38);    /*显示模式设置*/
  244.    DelayMs(5);
  245.    LCD_Write_Com(0x38);
  246.    DelayMs(5);
  247.    LCD_Write_Com(0x38);
  248.    DelayMs(5);
  249.    LCD_Write_Com(0x38);  
  250.    LCD_Write_Com(0x08);    /*显示关闭*/
  251.    LCD_Write_Com(0x01);    /*显示清屏*/
  252.    LCD_Write_Com(0x06);    /*显示光标移动设置*/
  253.    DelayMs(5);
  254.    LCD_Write_Com(0x0C);    /*显示开及光标设置*/
  255.    }


  256. /*------------------------------------------------
  257.               AD采集数据函数
  258. ------------------------------------------------*/
  259. //AD寄存器设置
  260. void AD_init(void)
  261. {
  262. uchar i;
  263. ADC_REST=1;
  264. ADC_CS=0;
  265. ADC_SCLK=1;
  266. ADC_DIN=0x42;
  267. for(i=0;i<8;i++)
  268. {
  269. ADC_SCLK=0;
  270. nop;
  271. ADC_SCLK=1;
  272. nop;
  273. }
  274. ADC_DIN=0x01;
  275. for(i=0;i<8;i++)
  276. {
  277. ADC_SCLK=0;
  278. nop;
  279. ADC_SCLK=1;
  280. nop;
  281. }
  282. ADC_DIN=0x00;
  283. for(i=0;i<8;i++)
  284. {
  285. ADC_SCLK=0;
  286. nop;
  287. ADC_SCLK=1;
  288. nop;
  289. }
  290. ADC_DIN=0x02;
  291. for(i=0;i<8;i++)
  292. {
  293. ADC_SCLK=0;
  294. nop;
  295. ADC_SCLK=1;
  296. nop;
  297. }
  298. }

  299. //AD数据读取
  300. void D_OUT(void)
  301. {
  302. uchar i;
  303. for(i=0;i<8;i++)
  304. {
  305. ADC<<=1;
  306. ADC_SCLK=1;
  307. ADC_X=ADC_DIN;
  308. nop;
  309. ADC_SCLK=0;
  310. nop;
  311. }
  312. ADC_L=ADC_X;
  313. for(i=0;i<8;i++)
  314. {
  315. ADC<<=1;
  316. ADC_SCLK=1;
  317. ADC_X=ADC_DIN;
  318. nop;
  319. ADC_SCLK=0;
  320. nop;
  321. }
  322. ADC_H=ADC_X;
  323. ad_result=ADC_H;
  324. ad_result=ad_result<<8;
  325. ad_result+=ADC_L;
  326. }
  327. /*------------------------------------------------
  328.               AD420输出4-20MA
  329. ------------------------------------------------*/
  330. void MaOut(unsigned int out_data)
  331. {
  332. unsigned char i;
  333. AD420_CLK=0;
  334. AD420_DATA=0;
  335. AD420_LATCH=0;
  336. for(i=0;i<16;i++)
  337. {
  338. if((out_data<<i) & 0x8000)
  339. {
  340. AD420_DATA=1;
  341. }
  342. else
  343. {
  344. AD420_DATA=0;
  345. }
  346. dms(10);
  347. AD420_CLK=1;
  348. dms(10);
  349. AD420_CLK=0;
  350. }
  351. dms(10);
  352. AD420_LATCH=1;
  353. dms(10);
  354. AD420_LATCH=0;
  355. AD420_CLK=0;
  356. AD420_DATA=0;
  357. }

  358. //将电势换算成温度
  359. float K_table(void)                  
  360. {
  361.         unsigned char i=0;
  362.         float tempt2,coff;
  363.         unsigned int temp1,temp3=0,temp4=0;
  364.         unsigned int hw_value = 25;
  365.         temp4=(hw_value)*(1692)/50;
  366. /*        if(volt_sign==0xff)
  367.         {
  368.                  volt=0;
  369.                 //return hw_value;
  370.         }*/
  371.         temp3=ad_result*4.194304*2+temp4;            //419.4304*2=32768*64/2500
  372.         for(i=0;i<28;i++)                   //查表
  373.         {
  374.                 if((temp3>=fendubiao_K[i])&&(temp3<fendubiao_K[i+1]))
  375.                 {
  376.                         coff=(float)(fendubiao_K[i+1]-fendubiao_K[i]);
  377.                         coff=50/coff;
  378.                         temp1=i*50;
  379.                         tempt2=(temp3-fendubiao_K[i])*coff+temp1;
  380.                 //        return tempt2-temp_RK;
  381.                 }
  382.         }
  383.         return 0xffff;
  384. }
  385. float S_table(void)         //S型将电势换算成温度函数        
  386. {
  387.         unsigned char i=0;
  388.         float tempt2,coff;
  389.         unsigned int temp1,temp3=0,temp4=0;
  390.         unsigned int hw_value = 25;
  391.         temp4=(hw_value)*(178)/10;
  392.         /*if(volt_sign==0xff)
  393.         {
  394.                  volt=0;
  395.                 return hw_value;
  396.         }*/
  397.         temp3=ad_result*16.777216+temp4; //1677.7216=32768*64/2500
  398.         for(i=0;i<178;i++)                   //查表
  399.         {
  400.                 if((temp3>=fendubiao_S[i])&&(temp3<fendubiao_S[i+1]))
  401.                 {

  402.                         coff=(float)(fendubiao_S[i+1]-fendubiao_S[i]);
  403.                         coff=10/coff;
  404.                         temp1=i*10;
  405.                         tempt2=(temp3-fendubiao_S[i])*coff+temp1;
  406.                 //        return tempt2-temp_RS;
  407.                 }
  408.         }
  409.         return 0xffff;
  410. }

  411. void Init_Timer0(void)
  412. {
  413.         TMOD |= 0x01;          //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响                     
  414.         TH0=(65536-20000)/256;                  //重新赋值 20ms
  415.         TL0=(65536-20000)%256;
  416.         EA=1;            //总中断打开
  417.         ET0=1;           //定时器中断打开
  418.         TR0=1;           //定时器开关打开
  419. }

  420. void Timer0_isr(void) interrupt 1
  421. {
  422.         TH0=(65536-20000)/256;                  //重新赋值 20ms
  423.         TL0=(65536-20000)%256;
  424.         time_20ms++;
  425.         if(time_20ms%10==0)                 //定时读取数据
  426.         {
  427.                 Read_AD=1;
  428.         }
  429. }
复制代码


回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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