|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 jianhong_wu 于 2015-7-11 11:50 编辑
坚鸿-深圳:
最近做项目需要用到CH452A按键扫描集成驱动芯片,现在把已经测试通过了的驱动代码分享给大家,供大家参考。
我用的是stm32f407单片机,主频率达到168MHz。
硬件连接简述:
CH452A芯片可以驱动8x8一共64个按键,但是本程序只是驱动4x4一共16个按键。硬件上行列扫描的连接是分别用CH452A芯片的DIG7至DIG4,以及SEG7至SEG4这8个引脚。
实现的功能:
每按一个按键都能让蜂鸣器发出一个短暂的声音。
main.c源文件代码如下:
- #include "stm32f4xx.h"
- #include "main.h"
- #include "led.h"
- #include "key.h"
- int main(void)
- {
- LED_Configuration();
- beep_Configuration();
- SysTick_Configuration();
- ch452_initial(); //跟按键有关的CH452A芯片初始化
- while (1)
- {
- key_service();
- }
- }
- void SysTick_Configuration(void) //SysTick定时器中断配置
- {
- if (SysTick_Config(SystemCoreClock / 1000))
- {
- while (1);
- }
- }
复制代码
SysTick的定时中断函数如下:
- void SysTick_Handler(void)
- {
- if(1==Gu8VoiceStart)
- {
- if(Gu16VoiceCnt!=0)
- {
- Gu16VoiceCnt--;
- beep_ON;
- }
- else
- {
- beep_OFF;
- Gu8VoiceStart=0;
- }
- }
- }
复制代码
key.c的源文件代码如下:
- #include "stm32f4xx.h"
- #include "key.h"
- #include "delay.h"
- u8 Gu8KeySec=0;
- u16 Gu16VoiceCnt=0;
- u8 Gu8VoiceStart=0;
- void beep_Configuration(void) //蜂鸣器IO口设置
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOF, ENABLE);
- GPIO_InitStructure.GPIO_Pin =GPIO_Pin_8;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
- GPIO_Init(GPIOF, &GPIO_InitStructure);
- }
- void ch452_initial(void)
- {
- if(key_board_config())
- KEY_INT_Config();
- }
- void Key_GPIO_Init(void) //按键IO口设置
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- EXTI_InitTypeDef EXTI_InitStructure;
- RCC_AHB1PeriphClockCmd(KEY_SDA_GPIO_Clock | KEY_SCL_GPIO_Clock, ENABLE);
- RCC_AHB1PeriphClockCmd(KEY_INT_GPIO_Clock, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
- GPIO_InitStructure.GPIO_Pin = KEY_SDA_PIN ;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
- GPIO_Init(KEY_SDA_GPIO,&GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = KEY_SCL_PIN ;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
- GPIO_Init(KEY_SCL_GPIO,&GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
- GPIO_InitStructure.GPIO_Pin = KEY_INT_PIN;
- GPIO_Init(KEY_INT_GPIO, &GPIO_InitStructure);
- SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOG, EXTI_PinSource6);
- EXTI_InitStructure.EXTI_Line = EXTI_Line6;
- EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
- EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
- EXTI_InitStructure.EXTI_LineCmd = ENABLE;
- EXTI_Init(&EXTI_InitStructure);
- }
- void KEY_INT_Config(void) //中断配置
- {
- NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
- NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- }
- void EXTI9_5_IRQHandler(void) //有按键被按下时,中断入口函数
- {
- if(EXTI_GetITStatus(EXTI_Line6)!= RESET )
- {
- key_scan(); //按键扫描和处理
- EXTI_ClearITPendingBit(EXTI_Line6);
- EXTI_ClearFlag(EXTI_Line6);
- }
- }
- void key_scan(void) //按键扫描和处理
- {
- u8 u8KeyRead;
- u8KeyRead = I2C_Read_Byte(0x6F);
- switch(u8KeyRead)
- {
- case 0x7F:
- Gu8KeySec=1;
- break;
- case 0x77:
- Gu8KeySec=2;
- break;
- case 0x6F:
- Gu8KeySec=3;
- break;
- case 0x67:
- Gu8KeySec=4;
- break;
- case 0x7E:
- Gu8KeySec=5;
- break;
- case 0x76:
- Gu8KeySec=6;
- break;
- case 0x6E:
- Gu8KeySec=7;
- break;
- case 0x66:
- Gu8KeySec=8;
- break;
- case 0x7D:
- Gu8KeySec=9;
- break;
- case 0x75:
- Gu8KeySec=10;
- break;
- case 0x6D:
- Gu8KeySec=11;
- break;
- case 0x65:
- Gu8KeySec=12;
- break;
- case 0x7C:
- Gu8KeySec=13;
- break;
- case 0x74:
- Gu8KeySec=14;
- break;
- case 0x6C:
- Gu8KeySec=15;
- break;
- case 0x64:
- Gu8KeySec=16;
- break;
- }
- }
- void key_service(void) //按键服务程序
- {
- switch(Gu8KeySec)
- {
- case 1:
- Gu16VoiceCnt=const_voice_short; //让蜂鸣器发出声音,操作的细节在SysTick定时器中断里
- Gu8VoiceStart=1;
- Gu8KeySec=0;
- break;
- case 2:
- Gu16VoiceCnt=const_voice_short;
- Gu8VoiceStart=1;
- Gu8KeySec=0;
- break;
- case 3:
- Gu16VoiceCnt=const_voice_short;
- Gu8VoiceStart=1;
- Gu8KeySec=0;
- break;
- case 4:
- Gu16VoiceCnt=const_voice_short;
- Gu8VoiceStart=1;
- Gu8KeySec=0;
- break;
- case 5:
- Gu16VoiceCnt=const_voice_short;
- Gu8VoiceStart=1;
- Gu8KeySec=0;
- break;
- case 6:
- Gu16VoiceCnt=const_voice_short;
- Gu8VoiceStart=1;
- Gu8KeySec=0;
- break;
- case 7:
- Gu16VoiceCnt=const_voice_short;
- Gu8VoiceStart=1;
- Gu8KeySec=0;
- break;
- case 8:
- Gu16VoiceCnt=const_voice_short;
- Gu8VoiceStart=1;
- Gu8KeySec=0;
- break;
- case 9:
- Gu16VoiceCnt=const_voice_short;
- Gu8VoiceStart=1;
- Gu8KeySec=0;
- break;
- case 10:
- Gu16VoiceCnt=const_voice_short;
- Gu8VoiceStart=1;
- Gu8KeySec=0;
- break;
- case 11:
- Gu16VoiceCnt=const_voice_short;
- Gu8VoiceStart=1;
- Gu8KeySec=0;
- break;
- case 12:
- Gu16VoiceCnt=const_voice_short;
- Gu8VoiceStart=1;
- Gu8KeySec=0;
- break;
- case 13:
- Gu16VoiceCnt=const_voice_short;
- Gu8VoiceStart=1;
- Gu8KeySec=0;
- break;
- case 14:
- Gu16VoiceCnt=const_voice_short;
- Gu8VoiceStart=1;
- Gu8KeySec=0;
- break;
- case 15:
- Gu16VoiceCnt=const_voice_short;
- Gu8VoiceStart=1;
- Gu8KeySec=0;
- break;
- case 16:
- Gu16VoiceCnt=const_voice_short;
- Gu8VoiceStart=1;
- Gu8KeySec=0;
- break;
- }
- }
- void SDA_IN_Config(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Pin = KEY_SDA_PIN;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
- GPIO_Init(KEY_SDA_GPIO,&GPIO_InitStructure);
- }
- void SDA_OUT_Config(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Pin = KEY_SDA_PIN;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
- GPIO_Init(KEY_SDA_GPIO,&GPIO_InitStructure);
- }
- u8 Get_edition(void)
- {
- u8 edition_value;
- I2C_Write_Byte(0x60,0x40);
- edition_value = I2C_Read_Byte(0x61);
- if(edition_value==0x20)
- return 1;
- else
- return 0;
- }
- void I2C_Stop(void)
- {
- delay(50);
- SCL_High;
- delay(50);
- SDA_High;
- delay(50);
- }
- void I2C_Start(void)
- {
- SDA_High;
- SCL_High;
- delay(50);
- SDA_Low;
- delay(50);
- SCL_Low;
- }
- void data_trans(u8 outdata)
- {
- u8 i;
- for(i=0;i<8;i++)
- {
- delay(20);
- if(outdata & 0x80)
- SDA_High;
- else
- SDA_Low;
- delay(30);
- SCL_High;
- delay(50);
- SCL_Low;
- outdata=outdata<<1;
- }
- delay(50);
- SDA_IN_Config();
- delay(10);
- SCL_High;
- }
- u8 data_receive(void)
- {
- u8 indata=0x00;
- u8 i;
- for(i=0;i<8;i++)
- {
- indata = indata<<1;
- delay(50);
- SCL_High;
- if(KEY_SDA_GPIO->IDR & KEY_SDA_PIN)
- indata=indata+1;
- delay(50);
- SCL_Low;
- }
- delay(50);
- SCL_High;
- return indata;
- }
- void I2C_Write_Byte(u8 reg_addr,u8 data)
- {
- I2C_Start();
- data_trans(reg_addr);
- while(ACK_STATE);
- delay(50);
- SDA_OUT_Config();
- SCL_Low;
- data_trans(data);
- while(ACK_STATE);
- delay(50);
- SCL_Low;
- SDA_OUT_Config();
- I2C_Stop();
- }
- u8 I2C_Read_Byte(u8 reg_addr)
- {
- u8 temp_data;
- I2C_Start();
- data_trans(reg_addr);
- while(ACK_STATE);
- delay(50);
- SCL_Low;
- temp_data=data_receive();
- delay(50);
- SDA_OUT_Config();
- I2C_Stop();
- return (temp_data);
- }
- u8 key_board_config(void)
- {
- Key_GPIO_Init();
- I2C_Write_Byte(0x6E,0x80);
- if(Get_edition())
- {
- I2C_Write_Byte(0x68,0x22);
- }
- return (1);
- }
复制代码
key.h的头文件代码如下:
- #ifndef _KEY_
- #define _KEY_
- #include "stm32f4xx_gpio.h"
- #define const_voice_short 100
- #define KEY_SDA_PIN GPIO_Pin_13
- #define KEY_SCL_PIN GPIO_Pin_3
- #define KEY_SDA_GPIO GPIOC
- #define KEY_SDA_GPIO_Clock RCC_AHB1Periph_GPIOC
- #define KEY_SCL_GPIO GPIOB
- #define KEY_SCL_GPIO_Clock RCC_AHB1Periph_GPIOB
- #define KEY_INT_PIN GPIO_Pin_6
- #define KEY_INT_GPIO GPIOG
- #define KEY_INT_GPIO_Clock RCC_AHB1Periph_GPIOG
- #define SDA_High GPIO_SetBits(KEY_SDA_GPIO,KEY_SDA_PIN)
- #define SDA_Low GPIO_ResetBits(KEY_SDA_GPIO,KEY_SDA_PIN)
- #define SCL_High GPIO_SetBits(KEY_SCL_GPIO,KEY_SCL_PIN)
- #define SCL_Low GPIO_ResetBits(KEY_SCL_GPIO,KEY_SCL_PIN)
- #define ACK_STATE KEY_SDA_GPIO->IDR & KEY_SDA_PIN
- #define beep_OFF GPIO_ResetBits(GPIOF , GPIO_Pin_8)
- #define beep_ON GPIO_SetBits(GPIOF , GPIO_Pin_8)
- void beep_Configuration(void);
- void Key_Init(void);
- void KEY_INT_Config(void);
- void Key_GPIO_Init(void);
- void Delay(__IO uint32_t nTime);
- void EXTI9_5_IRQHandler(void);
- void SDA_IN_Config(void);
- void SDA_OUT_Config(void);
- u8 I2C_Read_Byte(u8 reg_addr);
- void I2C_Write_Byte(u8 reg_addr,u8 data);
- void I2C_Start(void);
- void I2C_Stop(void);
- u8 data_receive(void);
- void data_trans(u8 outdata);
- u8 Get_edition(void);
- u8 key_board_config(void);
- void key_scan(void);
- void key_service(void);
- void ch452_initial(void);
- extern u8 Gu8KeySec;
- extern u16 Gu16VoiceCnt;
- extern u8 Gu8VoiceStart;
- #endif
复制代码
delay.c源文件如下:
- #include "stm32f4xx.h"
- #include "delay.h"
- void delay(unsigned long Delay11_MS)
- {
- unsigned long Delay11_us;
- for(Delay11_us=0;Delay11_us<Delay11_MS;Delay11_us++);
- }
复制代码
其它关联度不大的源文件就不再列出。
|
|