main.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //#define IsDebug
  3. //#define tim2Led
  4. //#define RxTestDebug
  5. ////////////////////////////////////////////////////////////////////////////////
  6. #include <iostm8s003f3.h>
  7. #define KEY0 KEY[0] //按键
  8. #define KEY1 KEY[1] //紧急按钮取消按键
  9. //==============================================================
  10. __root unsigned int BUS_RevBuf[30];
  11. __root unsigned char BUS_RevIndex=0;
  12. __root unsigned char BUS_Rev_Cmd[3]; //总线接收
  13. __root unsigned int BUS_RevOverTime=0; //总线接收超时,200
  14. __root unsigned char Bus_RevFlag=0; //总线接收成功
  15. //==============================================================
  16. __root unsigned char Ledswitch=2; //RedLED开关
  17. __root unsigned char KEY[2]={0}; //按键
  18. __root unsigned char CurrentCmd = 0; //当前命令类型
  19. //============================================
  20. __root unsigned char BUS_SendInex=0;
  21. __root unsigned char BUS_SendCmd[30]; //应用层发送数据
  22. __root unsigned char BUS_SendingCmd[30]; //定时器正在处理数据
  23. //==============================================================
  24. __root unsigned long LocalTime=0;
  25. __root unsigned char RunMode=0; //0:表示注册模式,>0表示正常工作模式
  26. __root unsigned char Bus_SendLength=146; //总线发送长度,在注册模式时长度为
  27. //==============================================================
  28. __root unsigned char BUS_SendCnt = 0; //重发计数
  29. __root const unsigned char BlankStr[28]="555555555555";
  30. __root const unsigned char DeviceSN[16]="SZFS20250120001";
  31. __root const unsigned char DeviceAddr[10]={0x31,0x08};
  32. __root const unsigned char *Addrp=0;
  33. void SysVar_Init(void);
  34. void BUS_RevData(void);
  35. void GPIO_KEY_Tick(void);
  36. void BUS_Rev_Tick(void);
  37. void BUS_SendData(unsigned char Length);
  38. void GPIO_MIC_SW(unsigned char status);
  39. //============================================
  40. #ifdef RxTestDebug
  41. unsigned long rxtestDebugcnt=0;
  42. #endif
  43. //==============================================================
  44. void SysVar_Init(void)
  45. {
  46. Addrp=DeviceAddr;
  47. RunMode=0;
  48. }
  49. //==============================================================
  50. void STM8_Init(void)
  51. {
  52. CLK_CKDIVR =0x18; //16M/8=2M
  53. }
  54. //==============================================================
  55. void GPIO_EXTI_Init(void)
  56. {
  57. EXTI_CR1_PCIS=1; //PC口为下降沿中断
  58. PC_DDR_DDR7=0;
  59. PC_CR1_C17=1;
  60. PC_CR2_C27=1;
  61. }
  62. void TIM2_Init(void)
  63. {
  64. TIM2_IER = 0x00; //禁止中断
  65. TIM2_PSCR = 0x04; //设置预分频寄存器数
  66. TIM2_ARRH =0xFF;
  67. TIM2_ARRL =0xFF;
  68. TIM2_CNTRH=0x00; //初值
  69. TIM2_CNTRL=0x00;
  70. TIM2_CR1 |= 0x01; //开启定时器
  71. }
  72. void GPIO_KEY_Init(void)
  73. {
  74. //==============================================
  75. PA_DDR_DDR1=0;
  76. PA_DDR_DDR2=0;
  77. PA_CR1_C11=1;
  78. PA_CR1_C12=1;
  79. PA_CR2_C21=0;
  80. PA_CR2_C22=0;
  81. //==============================================
  82. //==============================================
  83. PD_DDR_DDR4=0; // 设置为输入模式
  84. PD_CR1_C14=1; // 带上拉电阻输入
  85. PD_CR2_C24=0; // 禁用外部中断,只用查询方式
  86. //==============================================
  87. KEY0=0;
  88. KEY1=0;
  89. BUS_SendCnt =0;
  90. }
  91. void GPIO_LED_Init(void)
  92. {
  93. PD_DDR_DDR3 =1; //输出引脚
  94. PD_CR1_C13 =1; //推挽输出模式
  95. PD_ODR_ODR3 =0; //输出低电平,LED灭
  96. Ledswitch=2;
  97. }
  98. void TIM4_1ms_Init(void)
  99. {
  100. TIM4_PSCR = 0x03; //设置预分频寄存器数
  101. //共8种分频比例1(0),2(1),4(2),8(3),16(4),32(5),64(6),128(7)
  102. TIM4_ARR = 0xF9; //设置自动重装载寄存器
  103. TIM4_IER = 0x01; //开启TIM4更新事件中断使能
  104. TIM4_CNTR = 0xF9; //配置TIM4定时器初值,使得开始计数时发生第一次溢出
  105. TIM4_CR1_CEN= 0x01; //使能计数器功能TIM4_CR1寄存器CEN位为"1"
  106. }
  107. void TIM1_PWM_Init(void)
  108. {
  109. PC_DDR_DDR4 =1;
  110. //=============================================
  111. TIM1_PSCRH =0;
  112. TIM1_PSCRL =0; //定时器1 时钟不分频
  113. TIM1_ARRH =0;
  114. TIM1_ARRL =19; //定时器1的PWM输出频率:2000 000/20=100K
  115. TIM1_CR1 &=0x8F; //向上计数,边沿对齐模式
  116. //=============================================
  117. TIM1_CCR4H =0;
  118. TIM1_CCR4L =10;
  119. TIM1_CCMR4 =0x60; //配置CH4为PWM模式1
  120. TIM1_CCER2 &=0x1F; //配置CH4高电平有效
  121. //TIM1_CCER2 |=0x10; //使能CH4输出
  122. TIM1_OISR &=0xBF; //空闲输出低电平
  123. //通道4:100K_50% PWM输出
  124. //=============================================
  125. TIM1_CR1 |=0x01;
  126. TIM1_BKR =0x80;
  127. }
  128. void TIM2_PWM_Init(void)
  129. {
  130. // TIM2_IER = 0x04;
  131. // PD_DDR_DDR3 =1;
  132. //=============================================
  133. TIM2_CCMR2 = TIM2_CCMR2 | 0x70; //配置CH2为PWM模式1
  134. // TIM2_CCER1 &=0x1F; //配置CH2高电平有效
  135. TIM2_CCER1 = TIM2_CCER1 | 0x30; //使能CH2输出
  136. TIM2_ARRH =0;
  137. TIM2_ARRL = 19; //定时器1的PWM输出频率:2000 000/100=20K
  138. // TIM2_CR1 &=0x8F; //向上计数,边沿对齐模式
  139. //=============================================
  140. TIM2_CCR2H =0x0;
  141. TIM2_CCR2L =0x00;
  142. TIM2_PSCR =0; //0x03
  143. // TIM2_OISR &=0xBF; //空闲输出低电平
  144. //通道2:1K_50% PWM输出
  145. //=============================================
  146. TIM2_CR1 = TIM2_CR1 |0x01;
  147. // TIM2_BKR =0x80;
  148. }
  149. void GPIO_LED_Tick(void)
  150. {
  151. static unsigned long flashTime=0;
  152. static unsigned char ledflag=0;
  153. static unsigned char ledflagbak=0;
  154. #ifdef tim2Led
  155. if(Ledswitch==1)
  156. {
  157. //PD_ODR_ODR3=1;
  158. TIM2_CCR2H =0;
  159. TIM2_CCR2L =19;
  160. ledflag =0;
  161. }
  162. else if (Ledswitch==2)
  163. {
  164. if(LocalTime>flashTime)
  165. {
  166. flashTime=LocalTime+100;
  167. ledflag ++;
  168. }
  169. if (ledflagbak == ledflag ) {
  170. return;
  171. }
  172. ledflagbak = ledflag ;
  173. if(ledflag >39 ) {
  174. ledflag =0;
  175. }
  176. TIM2_CCR2H =0x0;
  177. if (ledflag > 19 ) {
  178. TIM2_CCR2L = (ledflag-19) ;
  179. } else if (ledflag > 15 ) {
  180. TIM2_CCR2L = (19-ledflag) ;
  181. ledflag = 20;
  182. }
  183. else {
  184. TIM2_CCR2L = (19-ledflag) ;
  185. }
  186. }
  187. else
  188. {
  189. TIM2_CCR2H =0x0;
  190. TIM2_CCR2L =0x0;
  191. ledflag =0;
  192. // PD_ODR_ODR3=0;
  193. }
  194. #else
  195. if(Ledswitch==1)
  196. {
  197. PD_ODR_ODR3=1;
  198. }
  199. else if (Ledswitch==2)
  200. {
  201. PD_ODR_ODR3=1;
  202. }
  203. else
  204. {
  205. PD_ODR_ODR3=0;
  206. }
  207. #endif
  208. }
  209. void GPIO_KEY_Tick(void)
  210. {
  211. static unsigned long keyTime1=0;
  212. static unsigned char keyResTime =0;
  213. static unsigned long keyTime2=0;
  214. static unsigned char keyResTime2 =0;
  215. // KEY0 处理
  216. if(PA_IDR_IDR1==1) //没有按下
  217. {
  218. if(KEY0==1)
  219. {
  220. keyResTime ++;
  221. if (keyResTime >= 200) {
  222. KEY0=2;
  223. }
  224. }
  225. else
  226. {
  227. KEY0=0;
  228. }
  229. keyTime1=LocalTime+120;
  230. }
  231. else if(LocalTime>keyTime1)
  232. {
  233. KEY0=1;
  234. keyResTime = 0;
  235. }
  236. else {
  237. keyResTime = 0;
  238. }
  239. // KEY1 处理
  240. if(PD_IDR_IDR4==1) //没有按下
  241. {
  242. if(KEY1==1)
  243. {
  244. keyResTime2 ++;
  245. if (keyResTime2 >= 200) {
  246. KEY1=2;
  247. }
  248. }
  249. else
  250. {
  251. KEY1=0;
  252. }
  253. keyTime2=LocalTime+120;
  254. }
  255. else if(LocalTime>keyTime2)
  256. {
  257. KEY1=1;
  258. keyResTime2 = 0;
  259. }
  260. else {
  261. keyResTime2 = 0;
  262. }
  263. }
  264. void BUS_RevData(void)
  265. {
  266. //=======================================
  267. if(((BUS_Rev_Cmd[0]!=Addrp[0])||(BUS_Rev_Cmd[1]!=Addrp[1]))&&(BUS_Rev_Cmd[2]!=0x0E))
  268. {
  269. if((BUS_Rev_Cmd[0]!=0xFF)||(BUS_Rev_Cmd[1]!=0xFF))
  270. return;
  271. }
  272. //=======================================
  273. switch(BUS_Rev_Cmd[2])
  274. {
  275. case 0:
  276. break;
  277. case 1:
  278. break;
  279. case 2:
  280. break;
  281. case 3:
  282. break;
  283. case 4: //主机呼叫分机,或主机应答分机
  284. break;
  285. case 5: //主机挂断分机
  286. break;
  287. case 6: //广播模式
  288. break;
  289. case 7: //打开门灯
  290. break;
  291. case 8: //关闭门灯
  292. break;
  293. case 9: //取消紧急呼叫
  294. RunMode=1;
  295. Ledswitch=0;
  296. BUS_SendCnt =0;
  297. break;
  298. case 13: //注册命令
  299. BUS_SendCmd[0]=Addrp[0];
  300. BUS_SendCmd[1]=Addrp[1];
  301. BUS_SendCmd[2]=0x0D;
  302. BUS_SendData(3);
  303. break;
  304. case 14:
  305. if(BUS_Rev_Cmd[1]=='Y') //转换盒已经注册过
  306. {
  307. Ledswitch=0;
  308. RunMode=1;
  309. Bus_SendLength=26; //总线发送长度,在正常工作模式时,为26 (3byes*8+2)
  310. }
  311. else
  312. {
  313. RunMode=0; //0:表示注册模式,>0表示正常工作模式
  314. Bus_SendLength=146;
  315. }
  316. break;
  317. }
  318. Bus_RevFlag=0xFF;
  319. }
  320. void BUS_Rev_Tick(void)
  321. {
  322. static unsigned char i=0,j=0,k=0;
  323. if(BUS_RevIndex==26)
  324. {
  325. BUS_Rev_Cmd[0]=0;
  326. BUS_Rev_Cmd[1]=0;
  327. BUS_Rev_Cmd[2]=0;
  328. for(k=0;k<24;k++)
  329. {
  330. i=k / 8;
  331. j=k % 8;
  332. if ((BUS_RevBuf[k]>280)&&(BUS_RevBuf[k]<400))
  333. {
  334. BUS_Rev_Cmd[i]|=(1<<j);
  335. }
  336. }
  337. BUS_RevIndex=0;
  338. i=(BUS_Rev_Cmd[0]+ BUS_Rev_Cmd[1]+(BUS_Rev_Cmd[2]&0x0F))&0x0F;
  339. j=(BUS_Rev_Cmd[2]>>4)&0x0F;
  340. #ifdef RxTestDebug
  341. if(i==j)
  342. {
  343. BUS_Rev_Cmd[2]=BUS_Rev_Cmd[2]&0x0F;
  344. BUS_RevData();
  345. } else {
  346. rxtestDebugcnt ++;
  347. if (rxtestDebugcnt > 10) //200ms,100s
  348. {
  349. Ledswitch=1;
  350. }
  351. }
  352. #else
  353. BUS_Rev_Cmd[2]=BUS_Rev_Cmd[2]&0x0F;
  354. BUS_RevData();
  355. #endif
  356. }
  357. }
  358. //===================TIM4计数溢出更新事件中断响应函数======================
  359. #pragma vector=0x19
  360. __interrupt void TIM4_UPD_OVF_IRQHandler(void)
  361. {
  362. __root static unsigned char flag=0;
  363. unsigned char i,j;
  364. TIM4_SR = 0; //清除更新事件中断标志位UIF
  365. LocalTime++;
  366. // if(BUS_RevOverTime>0)BUS_RevOverTime--;
  367. //===================================
  368. if(flag>1)
  369. {
  370. TIM1_CCER2_CC4E=1; //GPIOA->BSRR = GPIO_Pin_9; //总线为低电平
  371. flag--;
  372. return;
  373. }
  374. else if(flag==1)
  375. {
  376. TIM1_CCER2_CC4E=0; //GPIOA->BRR = GPIO_Pin_9; //总线为高电平
  377. flag=0;
  378. return;
  379. }
  380. //===================================
  381. if((BUS_SendInex>0)&&(flag==0))
  382. {
  383. if(BUS_SendInex==1) //起始位:总线5ms低电平
  384. {
  385. flag=5;
  386. TIM1_CCER2_CC4E=1; //GPIOA->BSRR = GPIO_Pin_9;
  387. BUS_SendInex++;
  388. }
  389. else if(BUS_SendInex<Bus_SendLength)
  390. {
  391. i=(BUS_SendInex-2)/8;
  392. j=(BUS_SendInex-2)%8;
  393. if(((BUS_SendingCmd[i]>>j)&0x01)>0) //数据位1:2ms低电平
  394. {
  395. flag=2;
  396. }
  397. else //数据位0:1ms低电平
  398. {
  399. flag=1;
  400. }
  401. TIM1_CCER2_CC4E=1; //GPIOA->BSRR = GPIO_Pin_9;
  402. BUS_SendInex++;
  403. }
  404. else if(BUS_SendInex==Bus_SendLength)
  405. {
  406. flag=0;
  407. TIM1_CCER2_CC4E=1; //GPIOA->BSRR = GPIO_Pin_9;
  408. BUS_SendInex++;
  409. }
  410. else
  411. {
  412. TIM1_CCER2_CC4E=0;
  413. BUS_SendInex=0;
  414. flag=0;
  415. }
  416. }
  417. }
  418. //===================外部IO下降沿中断事件中断响应函数=====================
  419. #pragma vector=0x07
  420. __interrupt void EXTI_PORTC_IRQHandler(void)
  421. {
  422. unsigned int i=0;
  423. //===========================================
  424. i=TIM2_CNTRH;
  425. i=(i<<8)+TIM2_CNTRL;
  426. //===========================================
  427. if(BUS_RevIndex==0)
  428. {
  429. //===========================================
  430. // BUS_RevOverTime=200; //接收200ms超时
  431. Bus_RevFlag=0; //清除接收标志位
  432. //===========================================
  433. if((i>400)&&(i<750))
  434. {
  435. BUS_RevIndex=2;
  436. }
  437. else
  438. {
  439. BUS_RevIndex=0;
  440. }
  441. }
  442. else if(BUS_RevIndex==1)
  443. {
  444. if((i>400)&&(i<750))
  445. {
  446. BUS_RevIndex=2;
  447. }
  448. else
  449. {
  450. BUS_RevIndex=0;
  451. }
  452. }
  453. else if(BUS_RevIndex<26)
  454. {
  455. BUS_RevBuf[BUS_RevIndex-2]=i;
  456. BUS_RevIndex++;
  457. }
  458. //===========================================
  459. TIM2_CNTRH=0x00; //初值
  460. TIM2_CNTRL=0x00;
  461. }
  462. void BUS_SendData(unsigned char Length)
  463. {
  464. // 添加发送前的状态检查
  465. if(BUS_SendInex > 0) {
  466. return; // 如果上一次发送未完成,直接返回
  467. }
  468. unsigned char i=0,checksum=0;
  469. //======================================================
  470. checksum=0;
  471. BUS_SendCmd[Length-1]&=0x0F;
  472. for(i=0;i<Length;i++)
  473. {
  474. checksum+=BUS_SendCmd[i];
  475. }
  476. BUS_SendCmd[Length-1]|=((checksum&0x0F)<<4);
  477. //计算校验值
  478. //======================================================
  479. for(i=0;i<Length;i++)
  480. {
  481. BUS_SendingCmd[i]=BUS_SendCmd[i];
  482. }
  483. BUS_SendInex=1;
  484. }
  485. int main( void )
  486. {
  487. static unsigned long KeySentTime=0;
  488. unsigned char i;
  489. unsigned long TurnOnDelay=3600000; //上电延时60分钟,自动进入工作模式
  490. unsigned char TurnOnMode=0;
  491. //========================================================
  492. STM8_Init();
  493. GPIO_EXTI_Init();
  494. #ifndef tim2Led
  495. TIM2_Init();
  496. #endif
  497. GPIO_LED_Init();
  498. TIM4_1ms_Init();
  499. GPIO_KEY_Init();
  500. TIM1_PWM_Init();
  501. #ifdef tim2Led
  502. TIM2_PWM_Init();
  503. #endif
  504. SysVar_Init();
  505. //========================================================
  506. asm("rim"); //改变主程序软件优先级"开启中断"
  507. while(1)
  508. {
  509. if ((TurnOnDelay<LocalTime)&&(TurnOnMode==0))
  510. {
  511. RunMode=1;
  512. Bus_SendLength=26; //总线发送长度,在正常工作模式时,为26 (3byes*8+2)
  513. TurnOnMode=0xFF;
  514. Ledswitch=0;
  515. }
  516. //====================================================
  517. BUS_Rev_Tick();
  518. GPIO_LED_Tick();
  519. GPIO_KEY_Tick();
  520. //===================================================
  521. if(RunMode==0)
  522. {
  523. if(KEY0==2)
  524. {
  525. BUS_SendCmd[0]=Addrp[0];
  526. BUS_SendCmd[1]=Addrp[1];
  527. for(i=0;i<15;i++)
  528. {
  529. BUS_SendCmd[2+i]=DeviceSN[i];
  530. }
  531. BUS_SendCmd[17]=0x0E;
  532. BUS_SendData(18);
  533. //在注册模式下,用户按键,则发送注册码!
  534. if(Ledswitch==0)
  535. {
  536. Ledswitch=2;
  537. }
  538. else
  539. {
  540. Ledswitch=0;
  541. }
  542. }
  543. }
  544. else
  545. {
  546. // 重发逻辑放在最前面处理
  547. if ((BUS_SendCnt) && (LocalTime> KeySentTime)) { //重发逻辑
  548. KeySentTime = LocalTime +1000;
  549. BUS_SendCnt--;
  550. BUS_SendCmd[0]=Addrp[0];
  551. BUS_SendCmd[1]=Addrp[1];
  552. BUS_SendCmd[2]=CurrentCmd; // 使用记录的命令类型
  553. BUS_SendData(3);
  554. }
  555. // 按键处理
  556. else if(KEY0==2) //紧急呼叫
  557. {
  558. BUS_SendCmd[0]=Addrp[0];
  559. BUS_SendCmd[1]=Addrp[1];
  560. BUS_SendCmd[2]=0x0C;
  561. BUS_SendData(3);
  562. Ledswitch=2;
  563. BUS_SendCnt = 9;
  564. KeySentTime = LocalTime +1000;
  565. CurrentCmd = 0x0C; // 记录当前命令类型
  566. }
  567. else if(KEY0==3) //长按关闭指示灯
  568. {
  569. Ledswitch=0; //dwd190802
  570. }
  571. else if(KEY1==2) //紧急呼叫取消
  572. {
  573. if(CurrentCmd == 0x0C) { // 只有在紧急呼叫状态下才能取消
  574. BUS_SendCmd[0]=Addrp[0];
  575. BUS_SendCmd[1]=Addrp[1];
  576. BUS_SendCmd[2]=0x07;
  577. BUS_SendData(3);
  578. Ledswitch=0;
  579. BUS_SendCnt = 9;
  580. KeySentTime = LocalTime +1000;
  581. CurrentCmd = 0x07; // 记录当前命令类型
  582. }
  583. }
  584. }
  585. }
  586. }