要实现的功能模块有四个:ir信号解码,待机信号重复按键判断,i2c从设备中断处理,LED&KEYPAD扫描。其中这四个模块中除了i2c从设备中断处理,其他都需要用到定时器。
不 巧的是,我们用到的单片机是HT46R22,只有一个定时器。我参考了操作系统时间片的概念,最终写了这个目前还觉得完美的代码。从测试结果来看,模块之 间没有互相干扰且工作良好。没采用时间片之前,ir信号到达时会导致LED闪烁,这样每次ir信号到达都会打断timer,而 LED&Keypad的扫描又依赖于timer调度,所以自然会产生闪烁现象)。但用时间片来解码ir信号,显著有一个缺点,就是脉冲宽度计算时 误差取值范围太大--达到一个时间片的大小。
写 完这个代码后,我还写了一个应用于单片机的task schedule和message box,简单的来说就是在这个程序上封装了一层,实现了insert_task_2_queue()和schedule_task()之类的函数。但是很 不巧,仿真器到期要归还给HT公司,这个代码虽已大致完成,但还没调试通过,这里就暂时保留吧。
关于代码,关于各模块原理,恕我这里不详述,因为涉及方面很广,我想谈却无从谈起。如果需要了解这份代码而又有各种困惑的,feel free to contact me by email。
另 外请不要轻易责怪电子工程师喜欢用全局变量,喜欢用数组而不是指针。我以前也这样,直到我用了HT-IDE 3000这个开发平台,不支持static变量,不支持指针,没有malloc和free。何况单片机程序最主要的是稳定,尤其当你面对的是OTP(一次 性编程)芯片。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #include <Ht46r22.h>
-
-
- #define uint8_t unsigned char
- #define uint16_t unsigned long
-
-
- #define crystal 8000000 // Crystal frequency
- #define PSC 16 // Prescaler stage
- #define nMS 0.25 // Timer interval: 0.25ms
- #define MS_IR_LEADER 5.44 // Leader code: 5.44ms
- #define MS_IR_CODE_0 0.76 // Code-0: 0.76ms,=(0.25ms * 3)
- #define MS_IR_CODE_1 1.73 // Code-1: 1.73ms,=(0.25ms * 7)
-
- #define IR_CUSTOM_CODE1 (0x80) // customer-code 1, Need convert BIT7~0 to bit0~7
- #define IR_CUSTOM_CODE2 (0xff) // customer-code 2
- #define IR_CUSTOM_CODE3 (0xff) // customer-code 3
- #define IR_CUSTOM_CODE4 (0x80) // customer-code 4
- #define IR_KEYVALUE_PWR1 (0x46) // standby-code 1
- #define IR_KEYVALUE_PWR2 (0x31) // standby-code 2
-
-
-
- #define TMR_nMS 0x82 // (0xff-((nMS*crystal/1000)/PSC)) Timer value for timing 0.25ms
- #define TMR_IR_0_nTIMES 3 // Code-0: 0.76ms=0.25ms*3
- #define TMR_IR_1_nTIMES 7 // Code-1: 1.73ms=0.25ms*7
- #define TMR_IR_SCALE 1 // Error range
-
- uint8_t tmr_ir_decode;
- uint8_t tmr_ir_repeat;
- uint8_t tmr_led_refresh;
-
-
- #define IR_FRAME_BITS 48 // Total bits of one frame data
- #define IR_FRAME_BYTES (IR_FRAME_BITS/8) // Length of one frame data
- uint8_t ir_bits_cnt;
- uint8_t ir_data[IR_FRAME_BYTES];
- uint8_t ir_data_ptr;
- bit ir_data_ready;
-
-
- #define STANDBY _pc0
- #define LOCK _pd0
-
-
- uint8_t pwr_repeat_cnt;
- bit pwr_flag;
-
-
- #define I2C_CMD_LED 0x80 // Led Refresh Command
- #define I2C_CMD_LOCK 0x40 // LOCK Refresh Command
- uint8_t i2c_cmd;
-
-
-
- #define LED_NUM 4
- #define LED_SET_DATA(x) do{_pbc = 0x00; _pb = x;}while(0)
- #define LED_EN_COM(x) do{_pa |= 0x0f; _pa &= ~(1<<(x));}while(0)
- #define LED_DIS_ALL_COMS() do{_pa |= 0x0f;}while(0)
-
- bit lock_status;
- uint8_t led_data[LED_NUM];
- uint8_t refresh_timeslice;
-
-
- #define I2C_SLAVE_ADDR 0x0c
- #define RX_LEN (LED_NUM+1) // commandword + data[0] + data[1] + data[2] + data[3]
-
- uint8_t tx_data;
- uint8_t rx_data[RX_LEN];
- uint8_t rx_data_ptr;
-
-
- #pragma vector isr_ext @ 0x4
- #pragma vector isr_tmr @ 0x8
- #pragma vector isr_i2c @ 0x10
-
-
- uint8_t byte_reverse(uint8_t dat)
- {
-
-
- uint8_t i;
- uint8_t src, dsn;
-
- src = dat;
- dsn = src & 0x1;;
- for(i = 0; i < 7; i++) {
- src >>= 1; dsn <<= 1;
- dsn |= src & 0x1;
- }
- return dsn;
- }
-
-
- void isr_ext()
- {
-
-
-
- uint8_t int_interval;
- int_interval = tmr_ir_decode;
- tmr_ir_decode = 0;
-
-
- if ((int_interval >= (TMR_IR_1_nTIMES-TMR_IR_SCALE))
- && (int_interval <= (TMR_IR_1_nTIMES+TMR_IR_SCALE))) {
-
- if (ir_data_ptr == IR_FRAME_BYTES) ir_data_ptr = 0;
- ir_data[ir_data_ptr] = (ir_data[ir_data_ptr]<<1) + 1;
- ir_bits_cnt++;
- if ((ir_bits_cnt%8) == 0) ir_data_ptr++;
- }
- else if ((int_interval >= (TMR_IR_0_nTIMES-TMR_IR_SCALE))
- && (int_interval <= (TMR_IR_0_nTIMES+TMR_IR_SCALE))) {
-
- if (ir_data_ptr == IR_FRAME_BYTES) ir_data_ptr = 0;
- ir_data[ir_data_ptr] = (ir_data[ir_data_ptr]<<1);
- ir_bits_cnt++;
- if ((ir_bits_cnt%8) == 0) ir_data_ptr++;
- }
- else {
-
- ir_data_ptr = 0;
- ir_bits_cnt = 0;
- ir_data_ready = 0;
- }
-
- if (ir_bits_cnt == IR_FRAME_BITS) {
-
- ir_data_ptr = 0;
- ir_bits_cnt = 0;
- ir_data_ready = 1;
- }
- }
-
- void isr_tmr()
- {
-
-
-
- tmr_ir_repeat++;
- if (tmr_ir_repeat > 200) {
-
- tmr_ir_repeat = 0;
- if (pwr_flag) {
- pwr_repeat_cnt++;
- if( pwr_repeat_cnt >= 6 ) pwr_flag = 0;
- }
- }
-
-
- tmr_led_refresh++;
- if (tmr_led_refresh > 8) {
-
- tmr_led_refresh = 0;
- refresh_timeslice++;
- refresh_timeslice %= (LED_NUM+1);
- }
-
-
- tmr_ir_decode++;
- }
-
- void isr_i2c()
- {
- if(_haas == 1) {
-
- if(_srw == 1) {
-
- _htx = 1;
- _hdr = tx_data;
- } else {
-
- _htx = 0;
- _txak = 0;
- rx_data[rx_data_ptr] = _hdr;
- }
- } else {
-
- if(_htx == 1) {
-
- if(_rxak == 1) {
- _htx = 0;
- _txak = 0;
- rx_data[rx_data_ptr] = _hdr;
- } else {
- _hdr = tx_data;
- }
- } else {
-
- rx_data[rx_data_ptr] = _hdr;
- rx_data_ptr++;
- if (rx_data_ptr == RX_LEN) {
-
- rx_data_ptr = 0;
-
- i2c_cmd = rx_data[0];
- switch (i2c_cmd) {
- case I2C_CMD_LED:
-
- led_data[0] = rx_data[1];
- led_data[1] = rx_data[2];
- led_data[2] = rx_data[3];
- led_data[3] = rx_data[4];
- break;
- case I2C_CMD_LOCK:
-
- lock_status = rx_data[1];
- break;
- }
- _txak = 1;
- } else {
-
- _txak = 0;
- }
- }
- }
- }
-
-
- void init_hw()
- {
-
-
-
-
-
-
-
-
- _intc0 = 0;
-
-
-
-
-
-
-
-
- _intc1 = 0;
-
-
-
-
-
-
-
-
-
-
-
- _tmrc = 0x84;
- _tmr = TMR_nMS;
-
-
-
-
-
-
-
-
-
- _hcr = 0;
-
-
-
-
-
-
-
- _pac = 0x20;
-
-
-
- _pbc = 0x00;
-
-
-
-
- _pcc = 0x00;
-
-
-
- _pdc = 0x00;
-
- _hadr = I2C_SLAVE_ADDR;
- _htx = 0;
- _txak = 0;
- _hen = 1;
-
- _ehi = 1;
- _eti = 1;
- _eei = 1;
- _emi = 1;
-
- _ton = 1;
-
- }
-
- void init_sys()
- {
- LOCK = 0;
- STANDBY = 1;
-
- ir_data_ptr = 0;
- ir_data_ready = 0;
- ir_bits_cnt = 0;
-
- tmr_ir_decode = 0;
- tmr_ir_repeat = 0;
- tmr_led_refresh = 0;
-
- pwr_flag = 0;
- pwr_repeat_cnt = 0;
-
- tx_data = 0xff;
- rx_data_ptr = 0;
-
-
- led_data[0] = 0x7c;
- led_data[1] = 0x5c;
- led_data[2] = 0x5c;
- led_data[3] = 0x78;
-
- i2c_cmd = 0xff;
- lock_status = 0;
- refresh_timeslice = 0;
- }
-
- void main()
- {
- uint8_t ir_custom_code[4];
- uint8_t ir_keyvalue_pwr[2];
-
- init_hw();
- init_sys();
-
- ir_custom_code[0] = byte_reverse(IR_CUSTOM_CODE1);
- ir_custom_code[1] = byte_reverse(IR_CUSTOM_CODE2);
- ir_custom_code[2] = byte_reverse(IR_CUSTOM_CODE3);
- ir_custom_code[3] = byte_reverse(IR_CUSTOM_CODE4);
- ir_keyvalue_pwr[0] = byte_reverse(IR_KEYVALUE_PWR1);
- ir_keyvalue_pwr[1] = byte_reverse(IR_KEYVALUE_PWR2);
-
- while (1) {
- if (refresh_timeslice < LED_NUM) {
-
- LED_EN_COM(refresh_timeslice);
- LED_SET_DATA(led_data[refresh_timeslice]);
- } else {
-
- LED_DIS_ALL_COMS();
- _pb = 0xff;
- _pbc= 0x7e;
- tx_data = _pb;
-
-
- LOCK = lock_status;
- }
-
- if (ir_data_ready) {
-
- if ((ir_data[0] == ir_custom_code[0]) && (ir_data[1] == ir_custom_code[1])
- &&(ir_data[2] == ir_custom_code[2]) && (ir_data[3] == ir_custom_code[3])
- &&(ir_data[4] == ir_keyvalue_pwr[0])&& (ir_data[5] == ir_keyvalue_pwr[1])) {
-
- if (pwr_flag == 0) {
- STANDBY = ~STANDBY;
- if (STANDBY == 1) {
-
- led_data[0] = 0x7c;
- led_data[1] = 0x5c;
- led_data[2] = 0x5c;
- led_data[3] = 0x78;
- } else {
-
- led_data[0] = led_data[1]= led_data[2] = led_data[3] = 0x40;
- lock_status = 0;
- }
- }
- pwr_flag = 1; pwr_repeat_cnt = 0;
- }
- ir_data_ready = 0;
- }
- }
- }
(sepnic) |