struct GPIO_PACK{
GPIO_TypeDef * port;
uint16_t pin;
}; //数码管 引脚对应的结构数组
struct GPIO_PACK segs[8]= {
{GPIOA,GPIO_PIN_15},
{GPIOA,GPIO_PIN_11},
{GPIOC,GPIO_PIN_9},
{GPIOC,GPIO_PIN_7},
{GPIOC,GPIO_PIN_8},
{GPIOA,GPIO_PIN_12},
{GPIOA,GPIO_PIN_8},
{GPIOC,GPIO_PIN_6},
} ;
struct GPIO_PACK bits[4]={
{GPIOD,GPIO_PIN_2},
{GPIOB,GPIO_PIN_4},
{GPIOB,GPIO_PIN_6},
{GPIOB,GPIO_PIN_7},
};
uint8_t shuzu[]={ //段码
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,
0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e
};
void DisplayOnebit(uint8_t digtal,uint8_t bit){
uint8_t i;
for(i=0;i<8;i++){
HAL_GPIO_WritePin(segs[i].port,segs[i].pin,(GPIO_PinState)(shuzu[digtal]&(0x01<<i)));
}
for(i=0;i<4;i++){
HAL_GPIO_WritePin(bits[i].port,bits[i].pin,(GPIO_PinState)(i!=bit));
}
}
void DisplayDigtal(uint16_t digtal){ // 调用这个函数使用数码管
int a=0;
DisplayOnebit(digtal%10,0);
HAL_Delay(5);
if (digtal>=10){
DisplayOnebit(digtal/10%10,1);
HAL_Delay(5);
if (digtal>=100){
DisplayOnebit(digtal/100%10,2);
HAL_Delay(5);
if (digtal>=1000){
DisplayOnebit(digtal/1000%10,3);
HAL_Delay(5);
}
}
}
}
// 扫描键盘
struct GPIO_PACK lie[4]={
{GPIOB,GPIO_PIN_0},
{GPIOB,GPIO_PIN_1},
{GPIOB,GPIO_PIN_13},
{GPIOB,GPIO_PIN_12}
};
struct GPIO_PACK hang[4]={
{GPIOA,GPIO_PIN_6},
{GPIOA,GPIO_PIN_7},
{GPIOC,GPIO_PIN_4},
{GPIOC,GPIO_PIN_5}
};
uint8_t connctt2[25]="The Key is ";
uint8_t *receive;
uint8_t receive_str[4]="0"; // 串口发送接收到的值
int number=0;
int receive_kye; //扫描键盘获取到的值
int get_key ; //串口发送的值 转换为int
int getkey_length=0; // 获取到的值的长度
void Int2Str(uint8_t* str, int intnum) // 将无符号整形整数intnum 转换成字符 str
{
int i, Div = 1000000000, j = 0, Status = 0;
for (i = 0; i < 10; i++)
{
str[j++] = (intnum / Div) + '0';
intnum = intnum % Div;
Div /= 10;
if ((str[j-1] == '0') & (Status == 0))
{
j = 0;
}
else
{
Status++;
}
}
}
int str2int1( char* str) // 字符串转整形
{
int temp = 0;
const char* p = str;
if(str == NULL) return 0;
if(*str == '-' || *str == '+')
{
str ++;
}
while( *str != 0)
{
if( *str < '0' || *str > '9')
{
break;
}
temp = temp*10 +(*str -'0');
str ++;
}
if(*p == '-')
{
temp = -temp;
}
return temp;
}
void Displaykeying()
{
uint8_t i,j,s,key=0;uint8_t k=1;
for(i=0;i<4;i++)
{ HAL_GPIO_WritePin(lie[i].port,lie[i].pin,GPIO_PIN_RESET);
for(s=0;s<4;s++){
if(i!=s)
HAL_GPIO_WritePin(lie[s].port,lie[s].pin,GPIO_PIN_SET);}
for(j=0;j<4;j++)
{ k=HAL_GPIO_ReadPin(hang[j].port,hang[j].pin);
if(k==0)
HAL_Delay(5);
if(k==0)
switch(j)
{
case 0:key=j+1+i;break;
case 1:key=j+4+i;break;
case 2:key=j+7+i;break;
case 3:key=j+10+i;break;
}
}
}
if (key !=0)
{
number = 1;
uint8_t key_str[5]; // 按下的键值 转换为字符型
//connctt2 ="The Key is ";
strcpy(connctt2,"The Key is ");
DisplayDigtal(key);
Int2Str(key_str,key); //把receive_key 按下的键值 转换为字符型key_str
strncat(connctt2,key_str,10); //把key_str 添加到connctt2后面
HAL_Delay(500);
HAL_UART_Transmit_IT(&huart1,connctt2,25);// 串口发送 值
}else
number = 0;
}
上面的都放到主函数上面 方便调用
5. 从串口接收到值 使用中断 对接收到的值处理
callback函数 (一般写在主函数 后面)
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//getkey_length = 4-huart1.RxXferCount;
uint8_t received[4];
for(int i=0;i<4;i++)
received[i]=receive_str[i];
HAL_I2C_Mem_Write(&hi2c2, ADDR_AT24C02_Write, 0, I2C_MEMADD_SIZE_8BIT,received,4, 10000);
HAL_UART_Transmit(&huart1,received,4,50);
HAL_UART_Receive_IT(&huart1, receive_str,4);
}
接收到值以后 先使用I2C写入 ,并使用串口发送 显示出来
最后开启下一个中断接受
6. while循环中 处理的事情
一直扫描键盘调用扫描键盘的函数,能够完成任务1,
将串口中断获取到的值转换为int型,并调用数码管进行展示,完成任务2
Displaykeying();
get_key = str2int1(receive_str);
DisplayDigtal(get_key);
#define ADDR_AT24C02_Write 0xA0
#define ADDR_AT24C02_Read 0xA1
#define BufferSize 0x100
读取EEPROM中的值,应该放在主函数中,while循环上面,每次开机能够读取到,并只读一次
HAL_I2C_Mem_Read(&hi2c2, ADDR_AT24C02_Read,0,I2C_MEMADD_SIZE_8BIT,receive_str,4,10000);
在获取到串口发送的值 就会写入到EEPROM,在callback函数中。
芯片不同 ,对引脚的处理不同,这个需要注意
但是方法都是一样的,代码的处理思路都可以参考
GitHub链接