LED
引脚PC8~PC15,默认高电平(灭)。
此外还要配置PD2为输出引脚(控制LED锁存) ,默认低电平(锁住)!!!
objectivec
#include "led.h"
void led_disp(unsigned char disp_led)
{
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_ALL,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,disp_led<<8,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
}
/*使用方法*/
unsigned char ledon=0x00;
led_disp(ledon|=0x01);//第一个led亮
led_disp(ledon|=0x04);//第三个led亮
led_disp(ledon&=~(0x01))//第一个led灭
led_disp(ledon&=~(0x08))//第四个led灭
KEY
选择PB0~PB2,PA0为输入模式,配置成上拉输入。 我们按键用的是定时器轮询检测按键状态(还能实现长按短按的功能)。
时钟源选择内部时钟,设置成100Hz,也就是10ms进一次中断,别忘了在NVIC Settings打勾 !
objectivec
#include "intterrupt.h"
struct keys
{
unsigned char sta;//引脚电平
unsigned char flag;//是否按下
unsigned char longflag;//是否长按
unsigned char judge;//进度标志位
unsigned int time;//长按时要用到
};
struct keys key[4]={0,0,0};
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIMX)
{
key[0].sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
key[1].sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
key[2].sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
key[3].sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
for(int i=0;i<4;i++)
{
switch(key[i].judge)
{
case 0:
{
if(key[i].sta==0)
{
key[i].judge=1;
key[i].time=0;
}
}
break;
case 1:
{
if(key[i].sta==0)
{
key[i].judge=2;
}
else
{
key[i].judge=0;
}
}
break;
case 2:
{
if(key[i].sta==1)//松手的时候根据time来判断长短按
{
key[i].judge=0;
if(key[i].time<200)//小于2s
{
key[i].flag=1;
}
}
else//没松手
{
key[i].time++;
if(key[i].time>200)//大于2s
{
key[i].longflag=1;
}
}
}
break;
}
}
}
}
/*使用方法*/
void key_proc(void)
{
if(key[0].flag==1)//按键1短按
{
//处理数据
key[0].flag=0;
}
if(key[3].longflag==1)//按键4长按
{
//处理数据
key[3].longflag=0;
}
}
key_proc()丢while里。
ADC
板子从左往右数第一个是PB15引脚(对应ADC2的通道15),第二个是PB12引脚(对应ADC1的通道11),采样周期选到最大,一定程度上能防止adc一直抖动。
objectivec
#include "myadc.h"
double adc_get(ADC_HandleTypeDef *pin)
{
unsigned int adc;
HAL_ADC_Start(pin);
adc=HAL_ADC_GetValue(pin);
//HAL_Delay(1);可不加
return adc*3.3/4096;
}
/*使用方法*/
adc_get(&hadc2);//获取第一个电压
adc_get(&hadc1);//获取第二个电压
PWM
假设题目要求我们在PA7引脚输出频率为1000Hz,占空比为50%的PWM波
注意所选定时器最好不要和按键中断的定时器共用 !
frq=80000000/800/100;duty=50/100;
objectivec
//在while之前启动PWM
HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);
/*设置占空比和频率*/
__HAL_TIM_SET_PRESCALER(&htim17,80000000/100/PWM_frq);//设置频率
__HAL_TIM_SetCompare(&htim17,TIM_CHANNEL_1,duty);//设置占空比
IC
PB4和PA15引脚用于输入捕获,测量频率。最好用TIM2和TIM3! 按键定时器等所有外设都设置好了再设置。
objectivec
#include "intterrupt.h"
unsigned int ccrl_val=0;
unsigned int frq=0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance==TIM2)
{
ccrl_val=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);
__HAL_TIM_SetCounter(htim,0);
frq=(80000000/80)/ccrl_val;
HAL_TIM_IC_Start_IT_(htim,TIM_CHANNEL_1);
}
//if(htim->Instance==TIM3)
//{
//
//}
//同上 再定义一个变量即可 注意在main里extern frq
}
/*使用方法*/
//在while之前启动IC 就可以在while里读frq
HAL_TIM_IC_Start_IT_(&htim2,TIM_CHANNEL_1);//启动第一个IC
HAL_TIM_IC_Start_IT_(&htim3,TIM_CHANNEL_1);//启动第二个IC
UART
记得手动选择PA9和PA10,波特率按题目要求,一般是9600。记得开中断!!!
objectivec
#include "interrupt.h"
#include "usart.h"
char rxdata[22];
unsigned char rxbit;
unsigned char rx_p;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
rxdata[rx_p++]=rxbit;
HAL_UART_Receive_IT(&huart1,&rxbit,1);
}
/*使用方法*/
include "string.h"//使用memset函数
//在while之前初始化 调用HAL_UART_Receive_IT(&huart1,&rxbit,1);
void uart_proc(void)
{
if(rx_p>0)
{
if(rx_p==x)//实际要接收的位数
{
//处理
}
else
{
//报错
}
rx_p=0;
memset(rxdata,0,22);//22要和你设置的rxdata长度一样
}
}
/*注意事项*/
//在while循环里这样写 防止接收不完整
while(1)
{
if(rx_p!=0)
{
uint8_t temp=rx_p;
HAL_Delay(1);
if(rx_p==temp)
{
uart_proc();
}
}
}
I2C
直接在官方给的i2c_hal.c里写,cubemxPB6和PB7直接选择输出模式。
objectivec
#include "i2c_hal.h"//官方的.c函数
void eeprom_write(unsigned char addr,unsigned char dat)
{
I2CStart();
I2CSendByte(0xa0);//0表示写
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
unsigned char eeprom_read(unsigned char addr)
{
unsigned char dat;
I2CStart();
I2CSendByte(0xa0);//0表示写
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CStop();
I2CStart();
I2CSendByte(0xa1);//1是读
I2CWaitAck();
dat=I2CReceiveByte();
I2CSendNotAck();//读出来之后发送非应答
I2CStop();
return dat;
}
八位无符号整型数据可以直接写和读,double类型的参考下图;
注意:每次写入都要延时5ms!!!