main.b.c 17 KB

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