一、题目展示

二、代码解析 

1、头文件的相关定义与声明

#ifndef _code_h
#define _code_h

#include "stm32g4xx.h"                  // Device header
#include "stdio.h"
#include "string.h"
#include "stdint.h"

#include "main.h"
#include "gpio.h"
#include "lcd.h"
#include "i2c_hal.h"
#include "usart.h"
#include "tim.h"

void lcd_proc(void);
void key_proc(void);
void led_proc(u8 led_x,u8 led_mode);
u8 i2c_read(u8 addr);
void i2c_write(u8 addr,u8 data);
void uasrt_proc(void);

#endif

2、主函数的初始化

#include "code.h" 
 
……

……

……


    extern u8 REP[2];
    extern double PRICE[2];
	if(i2c_read(0x88)!='N'&&i2c_read(0x99)!='B')//判断是否为初次上电,是的话则设置标志位
	{
		i2c_write(0x88,'N');//设置标志位
		i2c_write(0x99,'B');
		i2c_write(0x00,REP[0]);//写入数值
		i2c_write(0x01,REP[1]);
		i2c_write(0x02,PRICE[0]*10);
		i2c_write(0x03,PRICE[1]*10);
	}
	REP[0]=i2c_read(0x00);
	REP[1]=i2c_read(0x01);
	PRICE[0]=(double)i2c_read(0x02)/10;
	PRICE[1]=(double)i2c_read(0x03)/10;
	
	extern u8 my_pData;
	HAL_UART_Receive_IT(&huart1,&my_pData,1);
	
    while (1)
    {
		lcd_proc();
		key_proc();
		uasrt_proc();
    }

3、各个模块的编写

#include "code.h"

char tx_val[10];
u8 led_it_mode;
/*-----------------------------lcd--------------------------------*/
u8 ui;//界面参数
char lcd_val[30];//lcd显示数组
u8 SHOP[2],REP[2]={10,10};
double PRICE[2]={1.0,1.0};
void lcd_proc(void)
{
	if(ui==0)
	{
		sprintf(lcd_val,"        SHOP ");
		LCD_DisplayStringLine(Line1,(u8 *)lcd_val);
		sprintf(lcd_val,"     X:%d    ",SHOP[0]);
		LCD_DisplayStringLine(Line3,(u8 *)lcd_val);
		sprintf(lcd_val,"     Y:%d    ",SHOP[1]);
		LCD_DisplayStringLine(Line4,(u8 *)lcd_val);
//		sprintf(lcd_val,"     %d %d    ",i2c_read(0x00),i2c_read(0x01));
//		LCD_DisplayStringLine(Line8,(u8 *)lcd_val);
//		sprintf(lcd_val,"     %.1f %.1f    ",(double)i2c_read(0x02)/10,(double)i2c_read(0x03)/10);
//		LCD_DisplayStringLine(Line9,(u8 *)lcd_val);
	}
	else if(ui==1)
	{
		sprintf(lcd_val,"        PRICE ");
		LCD_DisplayStringLine(Line1,(u8 *)lcd_val);
		sprintf(lcd_val,"     X:%.1f    ",PRICE[0]);
		LCD_DisplayStringLine(Line3,(u8 *)lcd_val);
		sprintf(lcd_val,"     Y:%.1f    ",PRICE[1]);
		LCD_DisplayStringLine(Line4,(u8 *)lcd_val);
	}
	else
	{
		sprintf(lcd_val,"        REP ");
		LCD_DisplayStringLine(Line1,(u8 *)lcd_val);
		sprintf(lcd_val,"     X:%d    ",REP[0]);
		LCD_DisplayStringLine(Line3,(u8 *)lcd_val);
		sprintf(lcd_val,"     Y:%d    ",REP[1]);
		LCD_DisplayStringLine(Line4,(u8 *)lcd_val);
	}
}

/*-----------------------------key--------------------------------*/

u8 key_val[4];
u8 key_old[4];
u8 key;

void key_proc(void)
{
	for(u8 i=0;i<4;i++)
	{
		key_val[i] = HAL_GPIO_ReadPin(i<3?GPIOB:GPIOA,GPIO_PIN_0<<i%3);
	}
	for(u8 i=0;i<4;i++)
	{
		if(key_val[i]==0&&key_old[i]==1)
		{
			HAL_Delay(20);
			if(key_val[i]==0&&key_old[i]==1)
			{
				key=i+1;
			}
		}
	}
	for(u8 i=0;i<4;i++)
	{
		key_old[i]=key_val[i];
	}
	switch(key)
	{
		case 1:
		{
			ui++;
			ui%=3;
			LCD_Clear(Black);
			SHOP[0]=SHOP[1]=0;
			break;
		}
		case 4:
		{
			if(ui==0)
			{
				REP[0]=REP[0]-SHOP[0];
				REP[1]=REP[1]-SHOP[1];	
			    sprintf(tx_val,"X:%d,Y:%d,Z:%.1f",SHOP[0],SHOP[1],SHOP[0]*PRICE[0]+SHOP[1]*PRICE[1]);
				HAL_UART_Transmit(&huart1,(u8 *)tx_val,strlen(tx_val),50);
				SHOP[0]=SHOP[1]=0;
				i2c_write(0x00,REP[0]);
				i2c_write(0x01,REP[1]);		
				TIM3->CNT=0;
				led_proc(1,1);
				TIM2->CCR2=30;
			}
			break;
		}
		default ://按下B2和B3时
		{
			if(key)
			{
				if(ui==0)
				{
					SHOP[key-2]++;
					if(SHOP[key-2]>REP[key-2])
						SHOP[key-2]=0;
				}
				else if(ui==1)
				{
					PRICE[key-2]+=0.1;
					if(PRICE[key-2]>2.1)
						PRICE[key-2]=1.0;
					i2c_write(0x02+key-2,PRICE[key-2]*10);
				}
				else
				{
					REP[key-2]++;
					i2c_write(0x00+key-2,REP[key-2]);
				}
			}
		}
	}
	key=0;
	if(TIM3->CNT>50000)
	{
		led_proc(1,0);
		TIM2->CCR2=5;
	}
	if(REP[0]==0&&REP[1]==0)led_proc(2,led_it_mode);
	else led_proc(2,0);
}


/*-----------------------------led--------------------------------*/

void led_proc(u8 led_x,u8 led_mode)
{
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
	if(led_mode)
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8<<(led_x-1),GPIO_PIN_RESET);
	else
		HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8<<(led_x-1),GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}


/*-----------------------------usart--------------------------------*/
u8 my_pData;
char rx_val[10];

u8 count;
u8 rx_flag;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	rx_val[count]=my_pData;
	count++;
	rx_flag=1;
	TIM6->CNT=0;;
	HAL_UART_Receive_IT(&huart1,&my_pData,1);
}
void uasrt_proc(void)
{
	if(rx_flag==1)
	{
		if(TIM6->CNT>20)
		{
			if(rx_val[0]=='?')
			{
				sprintf(tx_val,"X:%.1f,Y:%.1f",PRICE[0],PRICE[1]);
				HAL_UART_Transmit(&huart1,(u8 *)tx_val,strlen(tx_val),50);
			}
			memset(rx_val,NULL,strlen(rx_val));
			count=0;
			rx_flag=0;
		}
	}
}


/*-----------------------------tim--------------------------------*/

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM4)
		led_it_mode=!led_it_mode;
}

u8 i2c_read(u8 addr)
{
	I2CStart();
	I2CSendByte(0xA0);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	I2CStop();
	
	I2CStart();
	I2CSendByte(0xA1);
	I2CWaitAck();
	u8 data=I2CReceiveByte();
	I2CSendNotAck();
	I2CStop();
	
	HAL_Delay(20);
	
	return data;
}
void i2c_write(u8 addr,u8 data)
{
	I2CStart();
	I2CSendByte(0xA0);
	I2CWaitAck();
	I2CSendByte(addr);
	I2CWaitAck();
	I2CSendByte(data);
	I2CWaitAck();
	I2CStop();
	
	HAL_Delay(20);
}

三、结语

难度还好,这一套应该注意I2C的使用,因为I2C的读取很慢,而这题又涉及到led闪烁,如果你频繁的使用I2C进行数据的读取,你会发现led的闪烁频率是不正常的。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐