找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1982|回复: 3
打印 上一主题 下一主题
收起左侧

STC15W408AS单片机串口通讯带串口移植功能+ADC采集+定时器+EEPROM综合程序

  [复制链接]
跳转到指定楼层
楼主
ID:280979 发表于 2023-7-11 13:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
【声明】此程序仅用于学习与参考!  
*********************************************************************/
  1. #include<STC15W408AS.h>
  2. #include<math.h>                  //计算小数点的头文件
  3. #include <intrins.h>          //用nop函数延时的头文件
  4. #define uchar unsigned char//宏定义无符号字符型
  5. #define uint unsigned int  //宏定义无符号整型
  6. /*数据类型定义*/
  7. typedef signed char        int8;
  8. typedef signed int        int16;
  9. typedef signed long        int32;
  10. typedef unsigned char        uint8;
  11. typedef unsigned int        uint16;
  12. typedef unsigned long        uint32;

  13. #define S1_S0 0x40    //P_SW3.6
  14. #define S1_S1 0x80    //P_SW3.7

  15. #define ENABLE_IAP 0x83 //系统工作时钟<12MHz 时,对IAP_CONTR 寄存器设置此值
  16. #define CMD_IDLE 0
  17. #define CMD_READ 1
  18. #define CMD_PROGRAM 2
  19. #define CMD_ERASE 3
  20. #define ENABLE_IAP 0x83//SYSCLK<12MH
  21. #define IAP_ADDRESS 0x0000        //存储地址
  22. #define FOSC 11059200L  
  23. #define BAUD 9600   

  24. #define ADC_POWER   0x80            //ADC电源控制位
  25. #define ADC_FLAG    0x10            //ADC完成标志
  26. #define ADC_START   0x08            //ADC起始控制位
  27. #define ADC_SPEEDLL 0x00            //540个时钟
  28. #define ADC_SPEEDL  0x20            //360个时钟
  29. #define ADC_SPEEDH  0x40            //180个时钟
  30. #define ADC_SPEEDHH 0x60            //90个时钟
  31. uint AD_H=0,AD_L=0,AD_Dat=0;
  32. /*定义遥控引脚*/
  33. sbit IN1 = P1^2;                        /*下*/
  34. sbit IN2 = P1^3;                        /*上*/
  35. sbit IN3 = P1^4;                        /*西*/
  36. sbit IN4 = P1^5;                        /*东*/
  37. sbit IN5 = P1^6;                        /*北*/
  38. sbit IN6 = P1^7;                        /*南*/
  39. sbit IN7 = P5^4;                        /*2*/
  40. sbit IN8 = P5^5;                        /*1*/
  41. /*AD采集引脚*/
  42. sbit ADC1=P1^1;//电池电压检测
  43. /*供电自锁引脚*/
  44. sbit gong_dian=P1^0;//电池电压检测
  45. /*指示灯引脚*/
  46. sbit RUN=P3^2;//运行指示灯
  47. sbit dian_chi=P3^3;//电池指示灯
  48. /*控制引脚*/
  49. sbit MD0=P3^4;//工作模式
  50. sbit MD1=P3^5;//工作模式

  51. uchar DATE=0x00;//遥控器按键
  52. uchar add=0X01; //遥控器地址

  53. bit write=0;
  54. bit flag_zx=0;
  55. uchar sendBuf[10];          //发送缓冲区
  56. uchar receBuf[10];    //接收缓冲区
  57. uchar r=0;//串口接收数据计数值
  58. uint tcnt=0;//定时器时间计数值
  59. uchar sec=0;//定时器时间计数值
  60. uchar k=100;//延时函数时间函数
  61. bit bz1=0;//输入按键标志
  62. bit bz2=0;//输入按键标志
  63. bit bz3=0;//输入按键标志
  64. bit bz4=0;//输入按键标志
  65. bit bz5=0;//输入按键标志
  66. bit bz6=0;//输入按键标志
  67. bit bz7=0;//输入按键标志
  68. bit bz8=0;//输入按键标志

  69. bit dian_liang_bj=0;//电量报警
  70. bit fa_she_bj=0;//数据发射标志

  71. uchar adc1=0;//AD采集的数据值
  72. /********************************************************************
  73.                             定义 ISP/IAP/EEPROM 命令
  74. *********************************************************************/

  75. void IapIdle();//禁用 ISP/IAP/EEPROM functionmake 单片机 在 一 安全 状态
  76. uint8 IapReadByte(uint16 addr);//读数据
  77. void IapProgramByte(uint16 addr, uint8 dat);//写数据
  78. void IapEraseSector(uint16 addr);//擦除数据
  79. void KEY1();//模式1函数
  80. void delay(uchar t);//擦除数据
  81. void clear_receBuf();//清空发送缓冲区
  82. void send_date1();//数据函数
  83. void senduart1();//发送函数
  84. void InitADC();//AD转换初始化程序
  85. uchar ADCRead(uchar px); //转换输出的数据 (PX为通道口)
  86. /********************************************************************
  87.                          AD转换初始化程序
  88. *********************************************************************/
  89. void InitADC()//AD转换初始化程序
  90. {
  91. P1ASF = 0x02;          //设置P1.1口AD转换,必须加//   P1M0=0X1E;
  92. ADC_RES = 0;                   //AD数据寄存器清空
  93. ADC_CONTR = ADC_POWER | ADC_SPEEDLL;//打开AD电源,转换周期210
  94. _nop_();                        //延时一个机器周期
  95. _nop_();
  96. _nop_();                        //延时一个机器周期
  97. }
  98. /********************************************************************
  99.                          AD转换控制程序
  100. *********************************************************************/
  101. uchar ADCRead(uchar px)          //转换输出的数据 (PX为通道口)
  102. {
  103.     ADC_CONTR = ADC_POWER | ADC_SPEEDLL |px| ADC_START;//开始转换
  104.     _nop_();                        //延时一个机器周期
  105.     _nop_();                                                //延时一个机器周期
  106.     _nop_();                                                //延时一个机器周期
  107.     _nop_();                                                //延时一个机器周期
  108.     while (!(ADC_CONTR & ADC_FLAG));//等待转换结束
  109.     ADC_CONTR &= ~ADC_FLAG;         //关闭AD转换
  110. //        AD_H = ADC_RES;                                        // 修改的 注:把高8位AD值付给AD_H
  111. //        AD_H <<= 2;                                           // 修改的  注:高八位左移2位
  112. //        AD_L = ADC_RESL & 0x03;                   // 修改的  注:取低两位
  113. //        AD_Dat =        AD_H | AD_L;          // 修改的          注:把高八位和低两位合并在一起
  114. //        AD_Dat =        AD_H | AD_L;          // 修改的          注:把高八位和低两位合并在一起
  115.     AD_Dat = ADC_RES;
  116.     return AD_Dat;                //返回数据
  117. }
  118. /********************************************************************
  119.                             延时函数
  120. *********************************************************************/
  121. void delay(uchar t)
  122. {
  123.   uchar i,j;
  124.    for(i=0;i<t;i++)
  125.    {
  126.             for(j=130;j>0;j--);
  127.          { ;
  128.          }
  129.    }
  130. }
  131. /****************数据函数*********************/
  132. void send_date1()//数据函数
  133. {         
  134. adc1=ADCRead(1);        
  135. sendBuf[0]=0xAA;
  136. sendBuf[1]=add;
  137. sendBuf[2]=adc1;
  138. sendBuf[3]=DATE;
  139. sendBuf[4]=0xBB;
  140. }
  141. /****************发送函数*********************/
  142. void senduart1()//发送函数
  143. {           
  144. SBUF=sendBuf[0];while(!TI);TI=0;
  145. SBUF=sendBuf[1];while(!TI);TI=0;
  146. SBUF=sendBuf[2];while(!TI);TI=0;
  147. SBUF=sendBuf[3];while(!TI);TI=0;
  148. SBUF=sendBuf[4];while(!TI);TI=0;
  149. }


  150. /********************************************************************
  151.                             模式1函数
  152. *********************************************************************/
  153. void KEY1()
  154. {
  155. //if(gong_dian==0){gong_dian=0;}
  156. if((IN1==0)&&(bz1==0)){delay(k);if((IN1==0)&&(bz1==0)){fa_she_bj=1;DATE=0x01;send_date1();senduart1();bz1=1;}}if((IN1==1)&&(bz1==1)){delay(k);if((IN1==1)&&(bz1==1)){bz1=0;fa_she_bj=0;}}//输入按键
  157. if((IN2==0)&&(bz2==0)){delay(k);if((IN2==0)&&(bz2==0)){fa_she_bj=1;DATE=0x02;send_date1();senduart1();bz2=1;}}if((IN2==1)&&(bz2==1)){delay(k);if((IN2==1)&&(bz2==1)){bz2=0;fa_she_bj=0;}}//输入按键
  158. if((IN3==0)&&(bz3==0)){delay(k);if((IN3==0)&&(bz3==0)){fa_she_bj=1;DATE=0x03;send_date1();senduart1();bz3=1;}}if((IN3==1)&&(bz3==1)){delay(k);if((IN3==1)&&(bz3==1)){bz3=0;fa_she_bj=0;}}//输入按键
  159. if((IN4==0)&&(bz4==0)){delay(k);if((IN4==0)&&(bz4==0)){fa_she_bj=1;DATE=0x04;send_date1();senduart1();bz4=1;}}if((IN4==1)&&(bz4==1)){delay(k);if((IN4==1)&&(bz4==1)){bz4=0;fa_she_bj=0;}}//输入按键
  160. if((IN5==0)&&(bz5==0)){delay(k);if((IN5==0)&&(bz5==0)){fa_she_bj=1;DATE=0x05;send_date1();senduart1();bz5=1;}}if((IN5==1)&&(bz5==1)){delay(k);if((IN5==1)&&(bz5==1)){bz5=0;fa_she_bj=0;}}//输入按键
  161. if((IN6==0)&&(bz6==0)){delay(k);if((IN6==0)&&(bz6==0)){fa_she_bj=1;DATE=0x06;send_date1();senduart1();bz6=1;}}if((IN6==1)&&(bz6==1)){delay(k);if((IN6==1)&&(bz6==1)){bz6=0;fa_she_bj=0;}}//输入按键
  162. if((IN7==0)&&(bz7==0)){delay(k);if((IN7==0)&&(bz7==0)){fa_she_bj=1;DATE=0x07;send_date1();senduart1();bz7=1;}}if((IN7==1)&&(bz7==1)){delay(k);if((IN7==1)&&(bz7==1)){bz7=0;fa_she_bj=0;}}//输入按键
  163. if((IN8==0)&&(bz8==0)){delay(k);if((IN8==0)&&(bz8==0)){fa_she_bj=1;DATE=0x08;send_date1();senduart1();bz8=1;}}if((IN8==1)&&(bz8==1)){delay(k);if((IN8==1)&&(bz8==1)){bz8=0;fa_she_bj=0;}}//输入按键
  164. //if((IN1==0)||(IN2==0)||(IN3==0)||(IN4==0)||(IN5==0)||(IN6==0)||(IN7==0)||(IN8==0)){RUN=0;}
  165. if(dian_liang_bj==0)
  166. {
  167. if((IN1==1)&&(IN2==1)&&(IN3==1)&&(IN4==1)&&(IN5==1)&&(IN6==1)&&(IN7==1)&&(IN8==1)){RUN=0;}//电量正常时绿灯亮
  168. }
  169. else{RUN=1;dian_chi;sec=0;}//当电池电量低时,红灯亮
  170. }
  171. /********************************************************************
  172.                             定时中断服务函数
  173. *********************************************************************/
  174. void t0(void) interrupt 1 using 0 //定时中断服务函数

  175. {
  176. tcnt++; //每过250ust tcnt 加一
  177. if(tcnt==400) //计满400 次(1/10 秒)时
  178. {
  179. tcnt=0; //重新再计
  180. sec++;
  181. if(dian_liang_bj==0){if(fa_she_bj==1){if(sec>=1){RUN=!RUN;sec=0;}}}               
  182. if(dian_liang_bj==1){if(sec>=20){dian_chi=!dian_chi;sec=0;}}

  183. //if(sec==10){RUN=!RUN;sec=0;}
  184. //if(sec>=20){dian_chi=!dian_chi;sec=0;}
  185. }
  186. }

  187. /*****************清空发送缓冲区*************************/
  188. void clear_receBuf()
  189. {
  190.     uchar i;
  191.         for(i=0;i<5;i++)
  192.         {
  193.             receBuf[i]=0;
  194.         }
  195. }
  196. /********************************************************************
  197.                             主函数
  198. *********************************************************************/
  199. void main()                                   
  200. {
  201.         
  202. P1M0 = 0x00; P1M1 = 0x02; //IO定义
  203. P3M0 = 0x00; P3M1 = 0x00; //IO定义

  204. SCON = 0x50;
  205. T2L = (65536 - (FOSC/4/BAUD));
  206. T2H = (65536 - (FOSC/4/BAUD))>>8;
  207. AUXR = 0x14;               
  208. AUXR |= 0x01;              
  209. ES = 1;                  
  210. EA = 1;
  211. add= IapReadByte(0x01);//读取存储的值
  212. if(add>=100){add=1;}
  213. //sj2= IapReadByte(0x02);//读取存储的值
  214. TMOD=0x02; //定时器工作在方式2
  215. TH0=0x06; //对TH0 TL0 赋值
  216. TL0=0x06;
  217. TR0=1; //开始定时
  218. ET0=1;
  219. EA=1;
  220. /*串口移植*/
  221. ACC = P_SW1;
  222. ACC &= ~(S1_S0 | S1_S1);    //S1_S0=1 S1_S1=0
  223. ACC |= S1_S0;               //(P3.6/RxD_2, P3.7/TxD_2)
  224. P_SW1 = ACC;  

  225. InitADC();//AD转换初始化程序
  226. sec=0;
  227. MD0 = 0;//工作模式
  228. MD1 = 0;//工作模式
  229. gong_dian=0;
  230. while(1)
  231. {         
  232. KEY1();//按键函数

  233. if(write==1)  //修改板子地址
  234. {
  235. write=0;
  236. add=1;
  237. IapEraseSector(0);  //擦除扇区
  238. IapProgramByte(0x01,add);//写入新的地址                           
  239. //IapProgramByte(0x02,sj2);//写入新的地址        
  240. }
  241. }               
  242. }
  243. /********************************************************************
  244.                             串口中断函数
  245. *********************************************************************/
  246. void Uart() interrupt 4 using 1
  247. {
  248. if (RI)
  249. {
  250. RI=0; //接收标志清零
  251. receBuf[r++&0x0F]=SBUF;     //把接受的数据存储到BUT数组中
  252. if(receBuf[0]!=0xaa){r=0;}
  253. if(r>=5)
  254. {        r=0;

  255. flag_zx=1;
  256. }
  257. }
  258. if(flag_zx==1)
  259. {                     

  260. flag_zx=0;

  261. if((receBuf[0]==0xaa)&&(receBuf[1]==0x00)&&(receBuf[2]==0x00)&&(receBuf[3]==0x00)&&(receBuf[4]==0xbb))
  262. {
  263. write=1;        
  264. sendBuf[0]=0xaa;
  265. sendBuf[1]=add;
  266. sendBuf[2]=0x00;
  267. sendBuf[3]=0x00;
  268. sendBuf[4]=0xbb;
  269. senduart1();                  
  270. }
  271. if((receBuf[0]==0xaa)&&(receBuf[1]==0xff)&&(receBuf[2]==0xff)&&(receBuf[3]==0xff)&&(receBuf[4]==0xbb))
  272. {
  273. sendBuf[0]=0xaa;
  274. sendBuf[1]=add;
  275. sendBuf[2]=0xff;
  276. sendBuf[3]=0xff;
  277. sendBuf[4]=0xbb;
  278. senduart1();                  
  279. }
  280. clear_receBuf();
  281. }
  282. }


  283. /********************************************************************
  284.                               结束
  285. *********************************************************************/
  286. void IapIdle(){//禁用 ISP/IAP/EEPROM functionmake 单片机 在 一 安全 状态
  287.     IAP_CONTR = 0;           //
  288.         IAP_CMD = 0;           //
  289.         IAP_TRIG = 0;           //
  290.         IAP_ADDRH = 0x80;  //
  291.         IAP_ADDRL = 0;           //
  292. }
  293. uint8 IapReadByte(uint16 addr){//读数据
  294.    uint8 dat;
  295.    IAP_CONTR = ENABLE_IAP;
  296.    IAP_CMD = CMD_READ;
  297.    IAP_ADDRL = addr;
  298.    IAP_ADDRH = addr >> 8;
  299.    IAP_TRIG = 0x5A;
  300.    IAP_TRIG = 0xA5;
  301.    _nop_();
  302.    dat = IAP_DATA;
  303.    IapIdle();
  304.    return dat;
  305. }
  306. void IapProgramByte(uint16 addr, uint8 dat){//写数据
  307.    IAP_CONTR = ENABLE_IAP;
  308.    IAP_CMD = CMD_PROGRAM;
  309.    IAP_ADDRL = addr;
  310.    IAP_ADDRH = addr >> 8;
  311.    IAP_DATA = dat;
  312.    IAP_TRIG = 0x5A;
  313.    IAP_TRIG = 0xA5;
  314.    _nop_();
  315.    IapIdle();
  316. }
  317. void IapEraseSector(uint16 addr){//擦除数据
  318.    IAP_CONTR = ENABLE_IAP;
  319.    IAP_CMD = CMD_ERASE;
  320.    IAP_ADDRL = addr;
  321.    IAP_ADDRH = addr >> 8;
  322.    IAP_TRIG = 0x5A;
  323.    IAP_TRIG = 0xA5;
  324.    _nop_();
  325.    IapIdle();
  326. }
  327. /********************************************************************
  328.                               结束
  329. *********************************************************************/
复制代码


STC15W408AS 串口 ADC 定时器 EEPROM.rar

57.87 KB, 下载次数: 109

Keil代码

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏8 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:97678 发表于 2023-7-12 07:35 | 只看该作者
好东西! 只是还没有看明白。学习之。
回复

使用道具 举报

板凳
ID:227484 发表于 2023-10-28 19:42 | 只看该作者
好东西,正在学习下载看看
回复

使用道具 举报

地板
ID:1085085 发表于 2023-10-30 09:53 | 只看该作者
感谢楼主的精彩分享,非常的权威!后续若需要更多的案例可参考ISP软件上的范例程序
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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