<pre class="cpp" name="code" snippet_file_name="blog_20131226_1_4357439" code_snippet_id="129080">
</pre><pre class="cpp" name="code" snippet_file_name="blog_20131226_1_4357439" code_snippet_id="129080">/* CT1642 总的来说,就是一个串口通讯的锁存器,也就是一个用MCU串口通讯,将18位数据发送到1642,1642锁存后,驱动数码管或者用于按键检测。
</pre><pre class="cpp" name="code" snippet_file_name="blog_20131226_1_4357439" code_snippet_id="129080">本人经过调试时,终于把CT1642给拿下了,还是同样道理,完成后,决定挺容易的,但过程还是有点坎坷。遇到的主要问题有:1:网上需找PDF不好找,找到的比较简要,没有注释重点和主要的时序要求,没有具体说明如何扫描按键:2:网上的例程,问题比较多,比如没有注明时序要求严格,常见的例程中的按键扫描无法实现功能,经个人分析,每个按键的扫描也是需要5ms间隔时间,也就是扫描一次COM口的时候就扫描一个按键,8个按键就需要8次总循环才能完成;3:是个注意点:扫描时,如果是3个COM,就用5MS扫描一次,4个COM,就用4ms扫描一次,不然数码管明显闪烁比较严重,因此我认为这个对时间要求比较严格。
</pre><pre class="cpp" name="code" snippet_file_name="blog_20131226_1_4357439" code_snippet_id="129080">*/
/*定义LED 数码管的位数,本驱动只实现3位和4位的操作,所以LED_BIT_COUNT的值只能是3或4*/#define LED_BIT_COUNT 4 /************************************************************************************************************************ 按键值定义 ***********************************************************************************************************************/#define CT_FUNCION_KEY 0x04//扫描时,扫描按键功能#define STB_KEY_MENU 0x01 #define STB_KEY_OK 0x02 #define STB_KEY_UP 0x04 #define STB_KEY_DOWN 0x08 #define STB_KEY_LEFT 0x10 #define STB_KEY_RIGHT 0x20 #define STB_KEY_EXIT 0x40 #define STB_KEY_NULL 0x00 #define P_CT_CLK PB3_OUT //CLK接口#define P_CT_DATA PB2_OUT //DATA 接口#define P_CT_KEY PC7_IN //按键接口#define CT_DATA_CLR P_CT_DATA=0#define CT_DATA_SET P_CT_DATA=1#define CT_CLK_CLR P_CT_CLK=0#define CT_CLK_SET P_CT_CLK=1const uint8 Lcd_tab[17]=//Q2接seg A Q9 接seg G 中间按顺序接 {0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,0x9E,0x8E};//共阴极const uint8 key_code[9] = /*定义按键顺序*/{ /*与Q9连接的按键*/ STB_KEY_MENU, /*与Q8连接的按键*/ STB_KEY_OK, /*与Q7连接的按键*/ STB_KEY_UP, /*与Q6连接的按键*/ STB_KEY_DOWN, /*与Q5连接的按键*/ STB_KEY_LEFT, /*与Q4连接的按键*/ STB_KEY_RIGHT, /*与Q3连接的按键*/ STB_KEY_LEFT, /*与Q2连接的按键*/ STB_KEY_EXIT, /*查询不到的按键*/ STB_KEY_NULL }; void Nop(uint8 T_Dly){ while(T_Dly--); return ;}/************************************************************************************************************************函数名称:ct1642_send_data()*功能说明:CT1642数据发送函数*输入参数:ct_data--显示数据 , ct_com--扫描com*返回参数:NULL*函数功能:该函数负责把1位LED数码管显示代码发送到CT1642当中,并显示出来,也即串并转换。***********************************************************************************************************************/static void ct1642_send_data(uint8 ct_dis_data, uint8 ct_com){ uint8 ct_addr; //存储数码管位置 uint8 i; switch(ct_com) { case 0: {ct_addr=0xef; ;break;} //显示C1位数据 数码管为共阴极,将要点亮的COM置0以显示该COM case 1: {ct_addr=0xdf; break;} //显示C2位数据 case 2: {ct_addr=0xbf; break;} //显示C3位数据 case 3: {ct_addr=0x7f; break;} //显示C4位数据 case 4: {ct_addr=0xff; break;} //扫描键盘,关闭COM1 default:{ct_addr=0xff; ct_dis_data=0x00;break;} } for(i=0;i<8;i++) //发送8位地址 { CT_CLK_CLR ; if( (ct_addr<<i)&0x80) { CT_DATA_SET; } else { CT_DATA_CLR; } CT_CLK_SET;//上升沿输出一位 } CT_DATA_CLR; //发送两个空位,补足要发送的18位 CT_CLK_CLR ; Nop(2);//此处根据单片机的指令周期而定 CT_CLK_SET; CT_DATA_CLR; CT_CLK_CLR ; Nop(2); CT_CLK_SET; for(i=0;i<8;i++) //发送8位数据 { CT_CLK_CLR ; if( (ct_dis_data<<i) & 0x80) { CT_DATA_SET; } else { CT_DATA_CLR; } CT_CLK_SET; } CT_CLK_SET; //输出数据 CT_DATA_CLR; Nop(2); CT_DATA_SET; CT_CLK_CLR ; CT_DATA_CLR; Nop(2); CT_DATA_SET; return;}/************************************************************************************************************************函数名称:ct1642_deal()*功能说明:CT1642方案面板管理函数*输入参数:NULL*返回参数:NULL*函数功能:该函数为CT1642方案前面板驱动程序接口函数,定义其为系统定时调用的函数,来实现LED数码管的动态显示和按键扫描。* 3位数码管5ms调用一次;4位数码管4ms调用一次 我本人在调试时,试过用5MS,数码管明显闪烁比较严重,因此我认为这个对时间要求比较严格***********************************************************************************************************************/void ct1642_deal(void){ static uint8 ct_addr= 0; static uint8 j=0; //面板管理控制变量 static uint8 KeyValue=0; uint8 key_val; uint8 temp; if(LED_BIT_COUNT==ct_addr) //按键扫描 { temp=(~(1<<j)); ct1642_send_data(temp,CT_FUNCION_KEY);// key_val=0; if(!P_CT_KEY) {//查询按键口 key_val=1;//有按键按下 } if(1==key_val) { KeyValue|=key_code[j]; } if(++j>=8) {//可进行按键处理--对应按键功能处理 j=0; KeyValue=0; } ct_addr=0; } else //LED扫描 { ct1642_send_data(v_LedCode[ct_addr],ct_addr);//送LED扫描 ct_addr++; } //return;}