led灯和锁存器
//灯要全设置和关
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
记住,不要和lcd混在一起!!!
建议不要用toggle
每次写的时候全部led都要写!
如果要用定时器中断来实现按键消抖,记得一定要开定时器中断模式
HAL_TIM_Base_Start_IT(&htim2);//要开时钟中断
void HAL_TIM_PeriodElapsedCallback (TIM_HandleTypeDef *htim)//定时器中断触发一次
ADC记得用过滤算法,我这里是中值滤波,还有用的是ADC-DMA模式
HAL_ADC_Start_DMA (&hadc2,A2,1);
int fliter()
{
int i=0,j=0,k=0;
int temp=0;
for(i=0;i<11;i++)
{
A1[i]=A2[0];
}
for(j=0;j<10;j++)
{
for(k=0;k<10-j;k++)
{
if(A1[k]<A1[k+1])
{
temp=A1[k+1];
A1[k+1]=A1[k];
A1[k]=temp;
}
}
}
return A1[5];
}
LCD_Init();
HAL_ADC_Start_DMA (&hadc2,A2,1);
LCD_Clear(Black);
LCD_SetBackColor(Black);
LCD_SetTextColor(White);
HAL_TIM_Base_Start_IT(&htim2);//要开时钟中断
//灯要全设置和关
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
YM1();//放在这里不会因为while闪屏幕
if(b==1)
{ b =0;
LCD_Clear(Black);
while(1)
{
YM2();
if(b==1)
{
b =0;
LCD_Clear(Black);
break;
}
}
}
/* USER CODE BEGIN 3 */
}
按键时钟计算公式
Tout = ((9999+1)×(79+1))/80 = 10000us = 10ms =10^-2 s 。
Hz = 80 × 10^6 / ( (9999+1)× (79+1) )= 100Hz
长按短按
void HAL_TIM_PeriodElapsedCallback( TIM_HandleTypeDef * htim )
{
if(htim->Instance == TIM16)
{
switch(a1)
{
case 1:{
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0)
{
a1=2;
}
}break;
case 2:{ //消抖后
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0)
{
a1=3;
}
else a1=1;
}break;
case 3:{
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)!=0)
{
b1=1; //短按界面切换
c=0;
a1=1;
}
else
{
c++;
a1=3;
}
}break;
default:break;
}
}
while (1)
{
YM1();
if(c>=200) //长按事件
{
c=0;
LCD_Clear(Black);
while(1)
{
YM2();
if(c>=200)
{
LCD_Clear(Black);
c=0;
b1=0; //由于长按过程中会出现b1=1,所以要0!!!
break;
}
}
}
if(b1==1) //短按
{
LCD_Clear(Black);
b1=0;
while(1)
{
YM2();
if(b1==1)
{
LCD_Clear(Black);
b1=0;
break;
}
}
}
IIC写EEPROM
//EEPROM
uint8_t read(uint8_t address)
{
unsigned char val;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(address);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
val = I2CReceiveByte();
I2CWaitAck();
I2CStop();
return(val);
}
//
void write(unsigned char address,unsigned char info)
{
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(address);
I2CWaitAck();
I2CSendByte(info);
I2CWaitAck();
I2CStop();
}
//循环里不能一直读,否则会出bug
//读一定要在写前面执行,不能写读,否则也会出bug255
不能同时写,一个一个写要。一起写读时中间要加延时10ms!!!读可以同时读
I2CInit();
user = read(0);
while (1)
{
//循环里不能一直读,否则会出bug
//读一定要在写前面执行,不能写读,否则也会出bug255
if(b1==1)
{
b1=0;
write(0,user);//按键按下就是写
break;
}
}
PWM捕获占空比
用作捕获的,频率一定要这样设置,否则计算出来的频率会出错。还有直接捕获那一个必须为上升沿!!!
输出PWM按正常就好,但是一定要记得设置占空比!!!否则测不出来
主函数里记得开启pwm和捕获中断
HAL_TIM_Base_Start_IT(&htim16); //按键的基本定时器中断开启
HAL_TIM_PWM_Start(&htim2 ,TIM_CHANNEL_2 );
HAL_TIM_IC_Start_IT (&htim3,TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT (&htim3,TIM_CHANNEL_2);
float Cap_val1,Cap_val2;
float Duty,Frequency;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
/*判断中断来源*/
if(htim ->Channel == HAL_TIM_ACTIVE_CHANNEL_1 )
{
/*读取寄存器的值*/
Cap_val1 = HAL_TIM_ReadCapturedValue (&htim3 ,TIM_CHANNEL_1 );
Cap_val2 = HAL_TIM_ReadCapturedValue (&htim3 ,TIM_CHANNEL_2 );
/*计算占空比,频率*/
if(Cap_val1 != 0)
{
__HAL_TIM_SetCounter(&htim3,0);
Duty = (float )(Cap_val2+ 1)*100 / (Cap_val1 +1) ;
Frequency = 80000000 / 80 / (float )(Cap_val1 +1) ;
}
}
}
RTC
获取数值的时候用这个函数HAL_RTC_GetTime (&hrtc,&TIME, RTC_FORMAT_BIN); BIN格式
BCD格式数值会跳变的很迷
还有HAL库设置的数值是奇怪转化为16进制的,例如11变为0x11。所以建议处理后再填
goto
可以跳出多重循环
但是一定要在同一个函数里写,不能跨函数!!!
while (1)
{
flag: //goto的标志位
YM1();
switch(b2)
{
case 0:
{
YM2();
if(b1==1) //返回键
{
LCD_Clear(Black);
b1=0;b2=0;
goto flag; //goto跳转到flag位置
}
}break;
}
}
USART
HAL_Delay(1000);