STM32 Cubemx实现串口通信、I2C与GPIO的综合应用

项目目标

  1. 通过按键,按下的值能够串口接受并显示出来,
  2. 串口发送数字,使用数码管显示数字。
  3. 将串口发送的数字使用I2C写入EEPROM,按复位键并能够读出来。
    效果演示
#### 使用模块 串口通信 I2C 键盘 数码管 查看原理图,找到相应的引脚 这个可以参考前面的文章 每个模块都单独讲了,这个项目综合功能使用
CubeMx配置
  1. 将数码管和键盘对应的GPIO口进行相应的设置
    键盘使用扫描法 行和列 分别设为input 和output 数码管设为output
    enter description here
  2. 使用USART1 并进行相应的配置
    enter description here
    NVIC Settings处 进行使能 ENable选中 打开中断
  3. I2C配置
    配置时钟 设置两个引脚 设置I2C参数
    (这个地方图参考 STM32 I2C介绍及cubemx配置)

代码设计

  1. 添加数码管 和键盘 封装好的代码
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}
};
  1. 一些变量声明
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; // 获取到的值的长度
  1. 由于 按键值是int性 发送到串口是str性,从串口接收是str性,给数码管展示是int性。
    所以需要int和str来回转换的代码
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;
}
  1. 扫描键盘获取到的键值直接进行处理 使用 中断发送 到串口
    (扫描法键盘 讲过 下面的处理有注释)
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);
  1. I2C读数据
    定义在外面 读和写的起始位置
#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链接

更多STM32学习教程

  1. STM32 cubemx keil5搭建学习环境
  2. 使用STM32 cubemx keil5实现led灯与数码管控制
  3. 基于STM32 CubeMx keil5实现键盘的应用
  4. 基于STM32 CubeMx keil5实现串口通信 I2C与GPIO综合应用
  5. 基于STM32 CubeMx keil5实现AD转换获取温度
  6. 基于STM32 CubeMx keil5 学习使用I2C
  7. 基于STM32 CubeMx keil5 学习使用串口通信
  8. 基于STM32 CubeMx keil5应用定时器
  9. 基于STM32 cubemx keil5学习使用中断
  10. 基于STM32 cubemx keil5综合应用实现温度控制系统
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用STM32CubeMX进行串口控制GPIO的配置时,首先需要打开STM32CubeMX并选择对应的芯片型号,比如stm32f103c8t6。然后可以进行时钟配置,根据需求选择配置。接下来,点击引脚标号,进行对应的GPIO配置。具体配置方法可以参考GitHub上的教程。需要注意的是,不同的芯片对引脚的处理可能会有所不同,所以在进行配置时需要注意芯片的特性。在配置完成后,可以生成代码并使用Keil等开发工具进行编程。通过编程,可以实现串口控制GPIO的功能,如控制LED灯、数码管等外部硬件设备。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [GPIO工作模式及CUBEMX的配置](https://blog.csdn.net/m0_62916400/article/details/124505157)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [STM32 Cubemx实现串口通信I2CGPIO综合应用](https://blog.csdn.net/Nirvana_6174/article/details/104320694)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值