|
#include "stm32f0xx.h"
GPIO_InitTypeDef GPIO_InitStruct;
unsigned char key=0;
#define SDA_1 GPIO_SetBits( GPIOB, GPIO_Pin_0);
#define SDA_0 GPIO_ResetBits( GPIOB, GPIO_Pin_0);
#define SCL_1 GPIO_SetBits( GPIOB, GPIO_Pin_1);
#define SCL_0 GPIO_ResetBits( GPIOB, GPIO_Pin_1);
void GPIO_Configuration(void);
void GPIO_Configuration(void)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;//0DIN 1dclk
GPIO_InitStruct.GPIO_Mode =GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_3;
GPIO_InitStruct.GPIO_OType=GPIO_OType_OD;
GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void EXTI_Configuration(void);
void EXTI_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStruct; //端口 结构体
NVIC_InitTypeDef NVIC_InitStruct; //中断嵌套 结构体
EXTI_InitTypeDef EXTI_InitStruct; //外部中断 结构体
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);//打开IO口的对应时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//系统配置控制器时钟使能,管理连接到GPIO口的外部中断
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_2;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_Level_2;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP ;
GPIO_Init(GPIOB,&GPIO_InitStruct);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB , EXTI_PinSource2);//设置中断源
EXTI_InitStruct.EXTI_Line=EXTI_Line2;
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStruct.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel=EXTI2_3_IRQn;//中断频道配置4-15通道
NVIC_InitStruct.NVIC_IRQChannelPriority=0;//优先级设为0
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;//使能通道
NVIC_Init(&NVIC_InitStruct);
}
///////////////////////////////////////////
void I2CStart(void);
void I2CStart(void)
{
SDA_1;
delay_us(5);
SCL_1;
delay_us(5);
SDA_0;
delay_us(5);
SCL_0;
delay_us(5);
}
void I2CStop(void);
void I2CStop(void)
{
SDA_0;
delay_us(5);
SCL_1;
delay_us(5);
SDA_1;
delay_us(5);
}
uint8_t I2CClock(void);
uint8_t I2CClock(void)
{
uint8_t I2C_bit;
SCL_1;
delay_us(4);
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_Level_2;
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;
GPIO_Init(GPIOB,&GPIO_InitStruct);
I2C_bit=GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0);
GPIO_InitStruct.GPIO_Mode =GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
GPIO_Init(GPIOB, &GPIO_InitStruct);
SCL_0;
delay_us(4);
return (I2C_bit);
}
void I2CAck(void);
void I2CAck(void)
{
SDA_0;
I2CClock();
SDA_1;
}
uint8_t I2CSend(unsigned char i2c_data);
uint8_t I2CSend(unsigned char i2c_data)
{
unsigned char i;
SCL_0;//SDA信号只能在SCL=0时改变,否则认为是控制信号
for(i=0;i<8;i++)
{
//---------数据建立----------
if(i2c_data&0x80)
{
SDA_1;
}
else
{
SDA_0;
}
i2c_data<<=1;
I2CClock();
}
SDA_1;//请求应答时保证SDA为高
return (~I2CClock());//若接收应答此时SDA为底
}
//////////////////////////////////////////////////////
unsigned char I2CReceive(void);
unsigned char I2CReceive(void)
{
unsigned char i,i2c_data=0;
for(i=1;i<8;i++)
{
if(I2CClock())//DCL为高电平期间SDA数据线的高低电平即为传送的数据位
i2c_data++;//若为1,则i2c_data加1
else
i2c_data=i2c_data<<1;//i2c_data左移一位依次接收发送的数据
}
return(i2c_data);
}
//////////////////////////////////////////
uint8_t Read_Data(uint16_t addr);
uint8_t Read_Data(uint16_t addr)
{
uint8_t data;
I2CStart();//发送开始信号
if(I2CSend(((uint8_t)(addr>>7))&0xfe|0x41))
{
data=I2CReceive();
I2CAck();
SDA_1;
I2CClock();
I2CStop();
return data;
}
else
return 0;
}
////////////////////////////////////////////////////////////////
void Write_CH452(unsigned char addr,unsigned char data);
void Write_CH452(unsigned char addr,unsigned char data)
{
I2CStart();//发送开始信号
if(I2CSend(addr<<1|0x40)&&I2CSend(data))//字节地址和数据均发送成功
{
I2CStop();//写入每个字节后发送一个停止位
delay_ms(10); //延时5~10ms
}
}
////////////////////////////////////////////
void Initial(void);
void Initial(void)
{
Write_CH452(0x07,0x00);//应答
Write_CH452(0x02,0x01);//复位
Write_CH452(0x07,0x00);//应答
Write_CH452(0x04,0x03);//开显示启用键盘扫描两线
Write_CH452(0x05,0x80);//译码极限3占空比10/16
}
void EXTI2_3_IRQHandler(void);
void main(void)
{
delay_init(48);
GPIO_Configuration();
EXTI_Configuration();
Initial();
while(1)
{
Write_CH452(0x0F,0);
}
}
void EXTI2_3_IRQHandler(void)
{
//while(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_2)==RESET);
key=Read_Data(0x0700);//读取按键代码
switch(key)
{
case 0X56: Write_CH452(0x0F,0);break;//16
case 0X76: Write_CH452(0x0E,1);break;//12
case 0X6e: Write_CH452(0x0D,2);break;//8
case 0X66: Write_CH452(0x0C,3);break;//4
case 0X7f: Write_CH452(0x0B,4);break;//14
case 0X77: Write_CH452(0x0A,5);break;//10
case 0X6f: Write_CH452(0x09,6);break;//6
case 0X67: Write_CH452(0x08,7);break;//2
}
EXTI_ClearITPendingBit(EXTI_Line2);
}
模拟I2C 从机CH452
哪位高手能帮我看看程序哪里错了?? |
|