• 蓝桥杯单片机综合练习——工厂灯光控制


    一、题目

    二、代码

    1. #include
    2. sfr AUXR = 0x8e; //定义辅助寄存器
    3. sbit S5 = P3^2; //定义S5按键引脚
    4. sbit S4 = P3^3; //定义S4按键引脚
    5. unsigned char led_stat = 0xff; //定义LED当前状态
    6. unsigned char count = 0; //定义50ms定时中断累计变量
    7. unsigned char t_h = 0; //定义运行时间的时变量
    8. unsigned char t_m = 0; //定义运行时间的分变量
    9. unsigned char t_s = 0; //定义运行时间的秒变量
    10. unsigned char command = 0; //定义串口命令字接受变量
    11. //========共阳极数码管的段码表============
    12. unsigned char code SMG_duanma[18]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,
    13. 0x82,0xf8,0x80,0x90,0x88,0x80,
    14. 0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
    15. //=======================================
    16. //============锁存器选择函数==============
    17. /**
    18. * @brief 选择要打通的锁存器
    19. * @param channel——要选择的通道
    20. * @retval 无
    21. **/
    22. void SelectHC573(unsigned char channel)
    23. {
    24. switch(channel)
    25. {
    26. case 4:
    27. P2 = (P2 & 0x1f) | 0x80;
    28. break;
    29. case 5:
    30. P2 = (P2 & 0x1f) | 0xa0;
    31. break;
    32. case 6:
    33. P2 = (P2 & 0x1f) | 0xc0;
    34. break;
    35. case 7:
    36. P2 = (P2 & 0x1f) | 0xe0;
    37. break;
    38. case 0:
    39. P2 = (P2 & 0x1f) | 0x00;
    40. break;
    41. }
    42. }
    43. //=======================================
    44. //=================延时函数==============
    45. /**
    46. * @brief 延时
    47. * @param t--延时长度
    48. * @retval 无
    49. **/
    50. void Delay(unsigned int t)
    51. {
    52. while(t--);
    53. }
    54. //=======================================
    55. //===========系统初始化函数==============
    56. /**
    57. * @brief 将蜂鸣器、继电器等无关设备关闭
    58. * @param 无
    59. * @retval 无
    60. **/
    61. void InitSystem()
    62. {
    63. SelectHC573(5);
    64. P0 = 0x00;
    65. SelectHC573(4);
    66. P0 = led_stat;
    67. SelectHC573(0);
    68. }
    69. //=======================================
    70. //===========设备检测函数================
    71. /**
    72. * @brief 逐个检测工厂灯光的工作状态
    73. * @param 无
    74. * @retval 无
    75. **/
    76. void CheckLED()
    77. {
    78. unsigned int i;
    79. SelectHC573(4);
    80. for(i = 0;i < 8; i++)
    81. {
    82. led_stat = 0xfe << i;
    83. P0 = led_stat;
    84. Delay(60000);
    85. Delay(60000);
    86. }
    87. for(i = 0;i < 8; i++)
    88. {
    89. led_stat = ~(0xfe << i);
    90. P0 = led_stat;
    91. Delay(60000);
    92. Delay(60000);
    93. }
    94. }
    95. /**
    96. * @brief 逐个检测数码管的工作状态
    97. * @param 无
    98. * @retval 无
    99. **/
    100. void CheckSMG()
    101. {
    102. unsigned int i;
    103. for(i = 0;i < 8; i++)
    104. {
    105. SelectHC573(6);
    106. P0 = ~(0xfe << i);
    107. SelectHC573(7);
    108. P0 = 0x00;
    109. Delay(60000);
    110. Delay(60000);
    111. }
    112. for(i = 0;i < 8; i++)
    113. {
    114. SelectHC573(6);
    115. P0 = 0xfe << i;
    116. SelectHC573(7);
    117. P0 = 0x00;
    118. Delay(60000);
    119. Delay(60000);
    120. }
    121. SelectHC573(0);
    122. }
    123. //=======================================
    124. //=========数码管显示函数================
    125. /**
    126. * @brief 在数码管指定位置上显示指定内容
    127. * @param pos——数码管选位
    128. value——数码管显示内容
    129. * @retval 无
    130. **/
    131. void DisplaySMG(unsigned char pos,unsigned char value)
    132. {
    133. P0 = 0xff;
    134. SelectHC573(6);
    135. P0 = 0x01 << pos;
    136. SelectHC573(7);
    137. P0 = value;
    138. }
    139. /**
    140. * @brief 在数码管上显示系统运行时间
    141. * @param 无
    142. * @retval 无
    143. **/
    144. void DisplayTime()
    145. {
    146. DisplaySMG(7,SMG_duanma[t_s % 10]); //秒的个位
    147. Delay(500);
    148. DisplaySMG(6,SMG_duanma[t_s / 10]); //秒的十位
    149. Delay(500);
    150. DisplaySMG(5,SMG_duanma[16]); //分隔符
    151. Delay(500);
    152. DisplaySMG(4,SMG_duanma[t_m % 10]); //分的个位
    153. Delay(500);
    154. DisplaySMG(3,SMG_duanma[t_m / 10]); //分的十位
    155. Delay(500);
    156. DisplaySMG(2,SMG_duanma[16]); //分隔符
    157. Delay(500);
    158. DisplaySMG(1,SMG_duanma[t_h % 10]); //时的个位
    159. Delay(500);
    160. DisplaySMG(0,SMG_duanma[t_h / 10]); //时的十位
    161. Delay(500);
    162. }
    163. //=======================================
    164. //===========定时器函数==================
    165. /**
    166. * @brief 将定时器T0设置为16位模式,计数初值为50ms
    167. * @param 无
    168. * @retval 无
    169. **/
    170. void InitTimer0()
    171. {
    172. TMOD = 0x21; //T0和T1定时器工作模式同时赋值
    173. TH0 = (65535 - 50000) / 256;
    174. TL0 = (65535 - 50000) % 256;
    175. ET0 = 1; //使能定时器T0
    176. EA = 1; //使能总中断
    177. TR0 = 1; //启动定时器T0
    178. }
    179. /**
    180. * @brief 进行系统运行时间的处理
    181. * @param 无
    182. * @retval 无
    183. **/
    184. void Timer0() interrupt 1
    185. {
    186. TH0 = (65535 - 50000) / 256;
    187. TL0 = (65535 - 50000) % 256;
    188. count ++;
    189. if(count == 20)
    190. {
    191. count = 0;
    192. t_s ++;
    193. }
    194. if(t_s == 60)
    195. {
    196. t_s = 0;
    197. t_m ++;
    198. if(t_m == 60)
    199. {
    200. t_m = 0;
    201. t_h++;
    202. }
    203. }
    204. }
    205. //=======================================
    206. //==============串口函数=================
    207. /**
    208. * @brief 将串口初始化为模式一,波特率为9600,允许接收
    209. * @param 无
    210. * @retval 无
    211. **/
    212. void InitUart()
    213. {
    214. TMOD = 0x21; //T0和T1定时器工作模式同时赋值
    215. TH1 = 0xfd; //设置9600波特率的参数
    216. TL1 = 0xfd;
    217. TR1 = 1; //启动定时器T1
    218. SCON = 0x50; //8为UART模式,允许接收
    219. AUXR = 0x00; //辅助寄存器设置
    220. ES = 1; //使能串口中断
    221. EA = 1; //使能总中断
    222. }
    223. /**
    224. * @brief 接收上位机的数据并保存在command变量中
    225. * @param 无
    226. * @retval 无
    227. **/
    228. void Uart() interrupt 4
    229. {
    230. if(RI == 1)
    231. {
    232. command = SBUF; //将接收到的数据保存到command中
    233. RI = 0; //接收完成后,将接收标志位RI清0
    234. }
    235. }
    236. /**
    237. * @brief 串口给上位机发送一个字节
    238. * @param dat——串口发送的内容
    239. * @retval 无
    240. **/
    241. void SendByte(unsigned char dat)
    242. {
    243. SBUF = dat; //把dat中的内容发送给上位机
    244. while(TI == 0);
    245. TI = 0; //发送完成后,将发送标志位RI清0
    246. }
    247. //=======================================
    248. //========上位机命令解析执行函数=========
    249. /**
    250. * @brief 接收上位机的数据并保存在command变量中
    251. * @param 无
    252. * @retval 无
    253. **/
    254. void ExecuteCommand()
    255. {
    256. if(command != 0x00) //接收到上位机命令
    257. {
    258. switch(command & 0xf0) //将命令类型取出来
    259. {
    260. case 0xa0: //远程控制灯光
    261. SelectHC573(4);
    262. led_stat = (led_stat | 0x0f) & (~command | 0xf0);
    263. P0 = led_stat;
    264. SelectHC573(0);
    265. command = 0x00;
    266. break;
    267. case 0xb0: //读取现场系统运行时间
    268. SendByte((t_h / 10 << 4) | (t_h % 10));
    269. SendByte((t_m / 10 << 4) | (t_m % 10));
    270. SendByte((t_s / 10 << 4) | (t_s % 10));
    271. command = 0x00;
    272. break;
    273. }
    274. }
    275. }
    276. //=======================================
    277. //==========按键扫描函数=================
    278. /**
    279. * @brief 扫描S4与S5按键并执行现场灯光控制
    280. * @param 无
    281. * @retval 无
    282. **/
    283. void ScanKeys()
    284. {
    285. if(S4 == 0)
    286. {
    287. Delay(500); //按键消抖
    288. if(S4 == 0) //确认按键按下
    289. {
    290. while(S4 == 0) //等待按键松开
    291. {
    292. DisplayTime();
    293. }
    294. SelectHC573(4);
    295. led_stat = (led_stat | 0x80) & (~led_stat | 0x7f);
    296. P0 = led_stat; //执行现场灯光控制
    297. SelectHC573(0);
    298. }
    299. }
    300. if(S5 == 0)
    301. {
    302. Delay(500); //按键消抖
    303. if(S5 == 0) //确认按键按下
    304. {
    305. while(S5 == 0) //等待按键松开
    306. {
    307. DisplayTime();
    308. }
    309. SelectHC573(4);
    310. led_stat = (led_stat | 0x40) & (~led_stat | 0xbf);
    311. P0 = led_stat; //执行现场灯光控制
    312. SelectHC573(0);
    313. }
    314. }
    315. }
    316. //=======================================
    317. //===============主函数==================
    318. void main()
    319. {
    320. InitSystem();
    321. CheckLED();
    322. CheckSMG();
    323. InitTimer0();
    324. InitUart();
    325. while(1)
    326. {
    327. ExecuteCommand();
    328. DisplayTime();
    329. ScanKeys();
    330. }
    331. }
    332. //=======================================
  • 相关阅读:
    Rocky(Centos)安装中文字体(防止中文乱码)
    Ubuntu16.04配置NTP时间同步
    WPS中配置MathType及mathtype实现论文公式一键改大小
    【目标检测】54、YOLO v7 | 又是 Alexey AB 大神!专为实时目标检测设计
    [MQ] SpringBoot使用扇型(广播)交换机/主题交换机
    Android学习笔记 1.2.3 Gradle的属性定义 && 1.2.4 增量式构建
    Boosting以及代表算法(Adaboost、GBDT)介绍
    【人工智能数学:01概率论】(2) 离散型概率空间
    LLVM TargetPassConfig
    JVM 内存模型和结构详解 (五大模型图解)
  • 原文地址:https://blog.csdn.net/weixin_71169037/article/details/134498590