概述
基于STM32F103C8开发板的嵌入式实验
1、连接USB TO TTL与STM32开发板:
- ① USB TO TTL端:
- ② STM32端:
连接GNN和VCC:
连接A9和A10:
- ③ STM32开发板:
- ④ 按钮与面包板:
2、STM32CubeMX准备:
- ① 安装STM32CubeMX:
- ② 新建工程:
- ③ 选择核心板的型号STM32F103C8:
④ 点击Help选项中的Install New Libraries进入库管理界面:
⑤ 下载cube库:
⑥ 由于在线下载太慢,还出错,最后选择手动导入cube库:
下面两个包顺序导入
- ⑦ 点击Project选项卡的setting,进入项目设置页面,填写项目相关信息(名称,位置以及工具链):
- ⑧ 选择接口,配置UART1:
- ⑨ 点击代码生成按钮:
3、安装Keil5:
4、 编写Cube程序,配置UART0为9600,8n1,上电后向串口输出“Hello”,在PC上通过串口软件观察结果:
- ① 实验中要用到PWR、TIM、UART,所以需要在stm32f1xx_hal_conf.h的开始解除对这些宏的注释:
- ② 配置uart,配置USART1,波特率为9600,8n1:
void UART0_Init(UART_HandleTypeDef UartHandle){
//配置UART1
UartHandle.Instance = USART1;
//设置波特率为9600
UartHandle.Init.BaudRate = 9600;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
//初始化UART
HAL_UART_Init(&UartHandle);
}
- ③ 在文件stm32f1xx_hal_msp.c中配置GPIO引脚:
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(huart->Instance==USART1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_USART1_CLK_ENABLE();
//配置GPIO引脚
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
}
- ④ main函数修改:
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
UART_HandleTypeDef UartHandle;
//端口设置函数
UART0_Init(UartHandle);
while (1)
{
//向串口传送长度为7的字符串Hello(包括后面的符号)
HAL_UART_Transmit(&UartHandle,(uint8_t*)"Hellorn",7,100);
HAL_Delay(100);
}
}
- ⑤ 准备编译:设置下图后build生成HEX文件:
点击build; - ⑥ 烧录程序:
下载烧录程序FlyMcu后打开:
选择待烧录的文件:
boot0置0,点击开始编程,迅速按下rst:
- ⑦ 串口显示:
打开putty观察结果:
5、编写Cube程序,配置PA11和PA12为内部上拉到输入模式,在main()函数循环检测PA11按钮按下,并在按钮按下时在串口输出“Pressed”:
- ① 对PA11和PA12配置为上拉输入模式:
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
__GPIOA_CLK_ENABLE();
//配置PA11和PA12为上拉输入模式
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
- ② 在main函数中用HAL_GPIO_ReadPin读取引脚输入:
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
UART_HandleTypeDef UartHandle;
while (1)
{
//通过HAL_GPIO_ReadPin读取引脚输入,判断如果按下按钮PA11,向串口传送数据
if((HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_11))==0){
HAL_UART_Transmit(&UartHandle,(uint8_t*)"Pressedrn",7,100);
}
HAL_Delay(100);
}
- ③ Build后通过FlyMcu烧录(和上一烧录步骤相同),打开Putty,按连接PA11的按键,观察结果:
6、 编写Cube程序,配置PA12下降沿触发中断,程序中设置两个全局变量,一个为计数器,一个为标识。当中断触发时,计数器加1,并设置标识。在循环中判断标识,如果标识置位则清除标识并通过串口输出计数值:
- PA12引脚的下降沿触发将会触发中断,进入函数EXTI15_10_IRQHandler,此
时在函数中调用HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12)表示查看PA12的值,如果符合条件,则触发HAL_GPIO_EXTI_Callback函数: - ① 配置PA12下降沿触发中断:
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
//配置PA12下降沿触发中断
- ② 设置中断优先级,enable中断向量表处理:
//设置中断优先级
HAL_NVIC_SetPriority(EXTI15_10_IRQn,0,0);
//enable中断向量表处理
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
- ③ 当PA12出现中断时,进入stm32f1xx_it.c中的EXTI15_10_IRHandler函数,在函数中调用HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12)表示查看PA12的值,如果符合条件,则触发HAL_GPIO_EXTI_Callback函数:
void EXTI15_10_IRQHandler(void){
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
}
- ④ 在main.c中函数HAL_GPIO_EXTI_Callback实现中断时处理:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
if (GPIO_Pin == GPIO_PIN_12){
//检测按下PA11按钮,设置标识
flag = 1;
//计数,即为PA12按下多少次
count ++;
}else{
UNUSED(GPIO_Pin);
}
}
- ⑤ Main函数中while循环处理:
while (1)
{
int cnt;
if (flag == 1){
//清除中断标识
flag = 0;
//输出
cnt = sprintf(str, "Press 12 : %d timesrn", count);
HAL_UART_Transmit(&UartHandle, (uint8_t*)str, cnt, 500);
}
- ⑥ Build后通过FlyMcu烧录程序,然后打开putty,多次按下PA12,观察结果:
7、编写Cube程序,开启定时器为200ms中断一次,中断触发时设置标识,主循环根据这个标识来做串口输出(取消4 的串口输出):
- ① 配置时钟向上计时,因为是200ms中断一次,则计数到199,Prescaler是分频值范围是0-65536。内部时钟频率为8MHz,则把分频值设置为8000,8MHz/8000=1000Hz=1ms,设置时钟源和复位模式:
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
void TIM_Init(){
TIM_Handle.Instance = TIM3;
TIM_Handle.Init.Prescaler = 8000;
//配置时钟向上计数
TIM_Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
TIM_Handle.Init.Period = 199;
//计数到199
HAL_TIM_Base_Init(&TIM_Handle);
//设置时钟源为内部时钟
sClockSourceConfig.ClockSource=TIM_CLOCKSOURCE_INTERNAL;
//设置复位模式
sMasterConfig.MasterOutputTrigger=TIM_TRGO_RESET;
}
- ② 在stm32f1xx_hal_msp.c中编写函数 HAL_TIM_Base_MspInit(TIM_HnadleTypeDef*
tim_base)和函数 HAL_TIM_Base_MspDeInit(TIM_HnadleTypeDef* tim_base):
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_base){
if(tim_base->Instance==TIM3)
{
__TIM3_CLK_ENABLE();
//设置中断优先级
HAL_NVIC_SetPriority(TIM3_IRQn,0,0);
//enable中断向量表处理
HAL_NVIC_EnableIRQ(TIM3_IRQn);
}
}
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_base){
if(tim_base->Instance==TIM3)
{
//关闭定时器时钟
__TIM3_CLK_DISABLE();
HAL_NVIC_DisableIRQ(TIM3_IRQn);
}
}
- ③ 在stm32f1xx_it.c中编写handler:
void TIM3_IRQHandler(void){
HAL_TIM_IRQHandler(&TIM_Handle);
}
- ④ 接下来HAL_TIM_IRQHandler(&TIM_Handle)函数会调用回调函数:
HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim):
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance==TIM3){
//标志
time_flag = 1;
//计数
time_count++;
}
}
- ⑤ 在main函数的while循环中,判断中断标识time_flag:
if(time_flag==1)
{
//清除标志位
time_flag=0;
//输出
cnt = sprintf(str, "Interrupt : %d timesrn", count);
HAL_UART_Transmit(&UartHandle, (uint8_t*)str, cnt, 500);
}
- ⑥ Build之后用FlyMcu进行程序烧录,成功后打开putty,观察结果,每隔200ms输出一次:
8、编写完整的码表程序,PA12的按钮表示车轮转了一圈,通过计数器可以得到里程,通过定时器中断得到的时间可以计算出速度;PA11的按钮切换模式,模式一在串口输出里程,模式二在串口输出速度:
① 按照要求,码表需要有两个模式,一个里程模式和一个速度模式。即将步骤7和8结合在一起。
② 在按下P11按钮时,切换模式,mode变量作为标志,最初设置为0—里程模式。
- ③ 回调函数:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
if (GPIO_Pin == GPIO_PIN_12){
flag = 1;
//按下PA12的次数,即里程
count ++;
}else if(GPIO_Pin == GPIO_PIN_11){
//检测到按下的键为PA11,切换模式
mode=!mode;
}
else{
UNUSED(GPIO_Pin);
}
}
- ④ 中断处理函数:
void EXTI15_10_IRQHandler(void){
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
}
- ⑤ 回调函数:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
time_flag=1;
time_count++;
//时间
if(time_count%5==0){
//模式一
if(mode==0){
//里程就是按PA12的次数
int distance=count;
//输出里程
int cnt=sprintf(str,"distance:%d rn",distance);
HAL_UART_Transmit(&huart1,(uint8_t*)str,cnt,500);
}
//模式二
else{
//计算速度
double velocity=count/(time_count/5.0);
//输出速度
int cnt=sprintf(str,"velocity:%d rn",velocity);
HAL_UART_Transmit(&huart1,(uint8_t*)str,cnt,500);
}
}
}
- ⑥ Build进行程序烧录,然后打开putty,按键以查看程序结果:
最后
以上就是长情钻石为你收集整理的LAb3-自行车码表的全部内容,希望文章能够帮你解决LAb3-自行车码表所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复