标题: 单片机io口模拟串口 1602显示数据位内容 [打印本页]

作者: huxiao    时间: 2015-1-24 15:25
标题: 单片机io口模拟串口 1602显示数据位内容
一个项目的一部分内容,让初学者模拟着做一下,还是很有用处的。

这样的程序可以实现一个51单片机有两个串口
  1. #include<regx52.h>

  2. sbit BT_SND =P1^1;
  3. sbit BT_REC =P1^0;

  4. //1602部分引脚定义
  5. sbit LCM_RW =P2^1 ;//定义引脚
  6. sbit LCM_RS =P2^0;
  7. sbit LCM_E =P2^2;
  8. #define LCM_Data P0
  9. #define Busy 0x80 //用于检测LCM状态字中的Busy标识

  10. #define F_TM F0

  11. #define TIMER0_ENABLE   TL0=TH0; TR0=1;
  12. #define TIMER0_DISABLE TR0=0;

  13. void WriteDataLCM(unsigned char WDLCM);
  14. void WriteCommandLCM(unsigned char WCLCM,BuysC);
  15. unsigned char ReadDataLCM(void);
  16. unsigned char ReadStatusLCM(void);
  17. void LCMInit(void);
  18. void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
  19. void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
  20. void Delay5Ms(void);
  21. void Delay400Ms(void);

  22. unsigned char code qq[] = {"Receive_Data"};
  23. //unsigned char code tel[] = {"Command:"};

  24. sbit ACC0=    ACC^0;
  25. sbit ACC1=    ACC^1;
  26. sbit ACC2=    ACC^2;
  27. sbit ACC3=    ACC^3;
  28. sbit ACC4=    ACC^4;
  29. sbit ACC5=    ACC^5;
  30. sbit ACC6=    ACC^6;
  31. sbit ACC7=    ACC^7;

  32. void IntTimer0() interrupt 1
  33. {
  34. F_TM=1;
  35. }

  36. //发送一个字符
  37. void PSendChar(unsigned char inch)
  38. {
  39. ACC=inch;

  40. F_TM=0;
  41. BT_SND=0; //start bit
  42. TIMER0_ENABLE; //启动
  43. while(!F_TM);

  44. BT_SND=ACC0; //先送出低位
  45. F_TM=0;
  46. while(!F_TM);

  47. BT_SND=ACC1;
  48. F_TM=0;
  49. while(!F_TM);

  50. BT_SND=ACC2;
  51. F_TM=0;
  52. while(!F_TM);

  53. BT_SND=ACC3;
  54. F_TM=0;
  55. while(!F_TM);

  56. BT_SND=ACC4;
  57. F_TM=0;
  58. while(!F_TM);

  59. BT_SND=ACC5;
  60. F_TM=0;
  61. while(!F_TM);

  62. BT_SND=ACC6;
  63. F_TM=0;
  64. while(!F_TM);

  65. BT_SND=ACC7;
  66. F_TM=0;
  67. while(!F_TM);


  68. BT_SND=1;
  69. F_TM=0;
  70. while(!F_TM);


  71. TIMER0_DISABLE; //停止timer


  72. }

  73. //接收一个字符
  74. unsigned char PGetChar()
  75. {
  76. TIMER0_ENABLE;
  77. F_TM=0;
  78. while(!F_TM); //等过起始位
  79. ACC0=BT_REC;

  80. TL0=TH0;

  81. F_TM=0;
  82. while(!F_TM);
  83. ACC1=BT_REC;

  84. F_TM=0;
  85. while(!F_TM);
  86. ACC2=BT_REC;

  87. F_TM=0;
  88. while(!F_TM);
  89. ACC3=BT_REC;

  90. F_TM=0;
  91. while(!F_TM);
  92. ACC4=BT_REC;

  93. F_TM=0;
  94. while(!F_TM);
  95. ACC5=BT_REC;

  96. F_TM=0;
  97. while(!F_TM);
  98. ACC6=BT_REC;

  99. F_TM=0;
  100. while(!F_TM);
  101. ACC7=BT_REC;


  102. F_TM=0;

  103. while(!F_TM)
  104. {
  105. if(BT_REC)
  106. {
  107. break;
  108. }
  109. }
  110. TIMER0_DISABLE; //停止timer
  111. return ACC;


  112. }
  113. //检查是不是有起始位
  114. bit StartBitOn()
  115. {
  116. return(BT_REC==0);

  117. }
  118. void main()
  119. {
  120. unsigned char gch,i;

  121. TMOD=0x22; /*定时器1为工作模式2(8位自动重装),0为模式2(8位自动重装) */

  122. PCON=00;

  123. TR0=0; //在发送或接收才开始使用
  124. TF0=0;
  125. TH0=(256-96); //9600bps 就是 1000000/9600=104.167微秒 执行的timer是104.167*11.0592/12= 96

  126. //            

  127. TL0=TH0;
  128. ET0=1;
  129. EA=1;
  130. Delay400Ms(); //启动等待,等LCM讲入工作状态
  131.    LCMInit(); //LCM初始化
  132.    Delay5Ms(); //延时片刻(可不要)
  133.    DisplayListChar(2, 0, qq);
  134. //    DisplayListChar(0, 1, tel);
  135.    // ReadDataLCM();//测试用句无意义
  136. PSendChar(0x55);
  137. PSendChar(0xaa);
  138. PSendChar(0x00);
  139. PSendChar(0xff);

  140. while(1)
  141. {


  142. if(StartBitOn())
  143.    {
  144.    gch=PGetChar();
  145.    PSendChar(gch);
  146.    for(i=0;i<8;i++)
  147.       DisplayOneChar(7-i,1, ((gch>>i)&0x01)+48);
  148.   
  149.     }
  150. }
  151. }


  152. //写数据
  153. void WriteDataLCM(unsigned char WDLCM)
  154. {
  155. ReadStatusLCM(); //检测忙
  156. LCM_Data = WDLCM;
  157. LCM_RS = 1;
  158. LCM_RW = 0;
  159. LCM_E = 0; //若晶振速度太高可以在这后加小的延时
  160. LCM_E = 0; //延时
  161. LCM_E = 1;
  162. }

  163. //写指令
  164. void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
  165. {
  166. if (BuysC) ReadStatusLCM(); //根据需要检测忙
  167. LCM_Data = WCLCM;
  168. LCM_RS = 0;
  169. LCM_RW = 0;
  170. LCM_E = 0;
  171. LCM_E = 0;
  172. LCM_E = 1;
  173. }

  174. /*/读数据
  175. unsigned char ReadDataLCM(void)
  176. {
  177. LCM_RS = 1;
  178. LCM_RW = 1;
  179. LCM_E = 0;
  180. LCM_E = 0;
  181. LCM_E = 1;
  182. return(LCM_Data);
  183. }
  184. */
  185. //读状态
  186. unsigned char ReadStatusLCM(void)
  187. {
  188. LCM_Data = 0xFF;
  189. LCM_RS = 0;
  190. LCM_RW = 1;
  191. LCM_E = 0;
  192. LCM_E = 0;
  193. LCM_E = 1;
  194. while (LCM_Data & Busy); //检测忙信号
  195. return(LCM_Data);
  196. }

  197. void LCMInit(void) //LCM初始化
  198. {
  199. LCM_Data = 0;
  200. WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
  201. Delay5Ms();
  202. WriteCommandLCM(0x38,0);
  203. Delay5Ms();
  204. WriteCommandLCM(0x38,0);
  205. Delay5Ms();

  206. WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
  207. WriteCommandLCM(0x08,1); //关闭显示
  208. WriteCommandLCM(0x01,1); //显示清屏
  209. WriteCommandLCM(0x06,1); // 显示光标移动设置
  210. WriteCommandLCM(0x0C,1); // 显示开及光标设置
  211. }

  212. //按指定位置显示一个字符
  213. void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
  214. {
  215. Y &= 0x1;
  216. X &= 0xF; //限制X不能大于15,Y不能大于1
  217. if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
  218. X |= 0x80; //算出指令码
  219. WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
  220. WriteDataLCM(DData);
  221. }

  222. //按指定位置显示一串字符
  223. void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
  224. {
  225. unsigned char ListLength;

  226. ListLength = 0;
  227. Y &= 0x1;
  228. X &= 0xF; //限制X不能大于15,Y不能大于1
  229. while (DData[ListLength]>0x20) //若到达字串尾则退出
  230. {
  231. if (X <= 0xF) //X坐标应小于0xF
  232. {
  233. DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
  234. ListLength++;
  235. X++;
  236. }
  237. }
  238. }

  239. //5ms延时
  240. void Delay5Ms(void)
  241. {
  242. unsigned int TempCyc = 5552;
  243. while(TempCyc--);
  244. }

  245. //400ms延时
  246. void Delay400Ms(void)
  247. {
  248. unsigned char TempCycA = 5;
  249. unsigned int TempCycB;
  250. while(TempCycA--)
  251. {
  252. TempCycB=7269;
  253. while(TempCycB--);
  254. };
  255. }
复制代码








欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1