历史上的今天
返回首页

历史上的今天

今天是:2025年02月14日(星期五)

正在发生

2019年02月14日 | stm32f1系列单片机实战应用

2019-02-14 来源:eefocus

最近有一个小项目,测量运动自行车速度,上传给上位机软件,处理VR视频播放。正好公司有现成的stm32f1系列单片机开发板,所以我就想到了使用它来实现这个小功能。



1. 硬件配置:


1.1. 运动自行车;



1.2. 磁感应开关与专用磁铁;    


   


1.3. 基于Stm32f103zet6芯片的开发板(七星虫),如下图;



1.4. 连接线若干;


1.5. miniusb线缆,用于给开发板供电及串口通信。



2. 系统描述与框图:


运动自行车车轮上安装5只磁铁,通过磁感应开关检测磁铁产生信号,接入stm32开发板PE0引脚。测量出的速度值通过串口发送给PC上位机软件(mini usb线缆连接)。硬件框图如下:



3. 软件实现


3.1.设定开发板PE0引脚下降沿中断,在引脚中断服务函数里累计中断次数(即磁感应开关感应到磁铁的次数),同时每累计10次LED2交换一次状态。外部初始化代码及中断服务函数如下:


void EXTIX_Init(void)

{

    EXTI_InitTypeDef EXTI_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;

    GPIO_InitTypeDef GPIO_InitStructure;

    //  引脚端口初始化 PE0

    GPIO_InitStructure.GPIO_Pin  = DEF_BIT_00;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

    GPIO_Init(GPIOE, &GPIO_InitStructure);    

     // 启 AFIO 时钟

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

    //GPIOE.0 中断线以及中断初始化配置,下降沿触发

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource0);// 配置中断线为0

    EXTI_InitStructure.EXTI_Line=EXTI_Line0;

    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发

    EXTI_InitStructure.EXTI_LineCmd = ENABLE;

    EXTI_Init(&EXTI_InitStructure); // 初始化中断线参数

    

    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                //使能按键外部中断通道

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;    //抢占优先级 2,

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;           //子优先级 2

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                 //使能外部中断通道

    NVIC_Init(&NVIC_InitStructure);                                 // 初始化 NVIC

}

// 外部中断0服务程序

long long lSpeedCnt = 0;

void EXTI0_IRQHandler(void)

{

    OSIntEnter();             // 告诉ucosii系统进入中断

    

    if(GPIO_ReadInputDataBit(GPIOE, DEF_BIT_00)==0) // PE0检测到下降沿

    {

        // 累计中断次数,每隔10次改变led1状态

        if(!((lSpeedCnt++)%10))

        {

            BSP_LED_Toggle(2);

        }

    }

    EXTI_ClearITPendingBit(EXTI_Line0); // 清除LINE0上的中断标志位

    

    OSIntExit             // 告诉ucosii系统退出中断

}


3.2.在启用一个定时器中断,周期为1s,在定时器中断服务函数里计算自行车的速度。计算方式如下:v = p / μ * C,其中:v是速度:m/s,p是磁感应开关感应频率, μ为车轮上安装磁铁个数:5,C为自行车车轮周长:1.38m。定时器中断初始化代码及中断服务函数如下:


/*******************************************************************************

* Function Name  : BSP_TIM2_Init

* Description    : Compute return latest speed measurement 

* Input          : None

* Output         : s16

* Return         : Return the speed in 0.1 Hz resolution.                    

*******************************************************************************/

static void BSP_TIM2_Init(u16 arr, u16 psc)

{

    TIM_TimeBaseInitTypeDef   bsp_tim2_init;    

    

    //使能TIM2时钟

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    

    

    TIM_DeInit(TIM2);

    TIM_TimeBaseStructInit(&bsp_tim2_init);

    //TIM2初始化

    bsp_tim2_init.TIM_Prescaler = psc;                                          //时钟预分频   定时器每隔 (psc+1)/72 us计数一次

    bsp_tim2_init.TIM_CounterMode = TIM_CounterMode_Up;                         //向上计数

    bsp_tim2_init.TIM_Period = arr;                                             //计数满(arr+1)次更新重装载寄存器数据

    bsp_tim2_init.TIM_ClockDivision = TIM_CKD_DIV1;                             //时钟不分频

//    bsp_tim2_init.TIM_RepetitionCounter = ;                                   //高级定时器用,这里不需设置

    TIM_TimeBaseInit(TIM2, &bsp_tim2_init);                                     //初始化定时器

    

    //设置定时器TIM2中断

    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);                                  //设置定时器更新中断

    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);                                 //清除中断标志,防止刚上电时进一次中断

    

    //初始化中断

    BSP_NVIC_Init(TIM2_IRQn, 3, 3); 

    

    //使能定时器TIM2

    TIM_Cmd(TIM2, ENABLE);

}

long long lvalCur;

long long lValPrev;

float fSpeedVal;

void TIM2_IRQHandler(void)

{

    OSIntEnter();             // 告诉ucosii系统进入中断

    

    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)

    {      

      extern long long lSpeedCnt;

      

      lvalCur = lSpeedCnt;

      fSpeedVal = (float)lvalCur - (float)lValPrev;

      fSpeedVal /= 5.0;

      fSpeedVal *= 1.38;      

      lValPrev = lvalCur;

      TIM_ClearFlag(TIM2, TIM_IT_Update);

    }

    OSIntExit();             // 告诉ucosii系统退出中断

 

}

3.3.系统共有两个任务,其中一个任务每50ms发送一次速度值给PC机,另一个控制LED1闪烁,周期100ms,用于指示系统正常运行。


第一个任务中运行代码如下:


 while(DEF_TRUE)

    {              

        extern float fSpeedVal;

        if((int)(fSpeedVal*100) > 9999)

        {

            printf("9999"); 

        }

        else if((int)(fSpeedVal*100) > 999)

        {

            printf("%d",(int)(fSpeedVal*100)); 

        }

        else if((int)(fSpeedVal*100) > 99)

        {

            printf("0%d",(int)(fSpeedVal*100)); 

        }

        else if((int)(fSpeedVal*100) > 9)

        {

            printf("00%d",(int)(fSpeedVal*100)); 

        }

        else

        {

            printf("000%d",(int)(fSpeedVal*100)); 

        }     

        

        OSTimeDlyHMSM(0, 0, 0, 80);

    }        

第二个任务中代码如下:


while (DEF_TRUE)

    {     

        BSP_LED_Toggle(1);  

        OSTimeDlyHMSM(0, 0, 0, 100);

    }

整体运行稳定,满足项目需求。

推荐阅读

史海拾趣

Altus Technology Inc公司的发展小趣事

随着公司规模的不断扩大,Altus开始实施全球化战略,积极拓展海外市场。公司通过与国际知名企业的合作,成功将产品打入国际市场,并建立了完善的销售网络和客户服务体系。同时,Altus还积极参与国际电子行业的交流和合作,不断吸收和引进国际先进技术和管理经验,提升了公司的整体竞争力。

Global Communications公司的发展小趣事
由于温度传感器本身也会受到温度变化的影响而产生测量误差(即温漂),因此需要选择具有低温漂特性的温度传感器,并在电路设计中采取适当的措施来抑制温漂现象。
Euroquartz公司的发展小趣事

Euroquartz自创立之初,就将产品质量和客户满意度置于公司运营的核心。为了确保这一点,公司引入了完整的AS9100 Rev D质量体系,并通过了相应的认证。这一体系要求Euroquartz在制造程序和可追溯性方面保持完整的记录,审批机关会定期进行审核,确保品质始终如一。这种对品质的执着追求,为Euroquartz赢得了客户的信赖,也为公司的发展奠定了坚实的基础。

Elytone Electronics Co Ltd公司的发展小趣事

近年来,Elytone公司积极响应国家环保政策,致力于推动绿色发展。他们采用环保材料和清洁能源进行生产,减少了对环境的污染。同时,公司还加强了对废弃物的回收和处理工作,实现了资源的循环利用。这些举措不仅提升了公司的社会形象,也为行业的可持续发展做出了积极贡献。

Anaheim Automation公司的发展小趣事

2005年,AMOTECH被Deloitte评为“亚太技术500强”,这进一步提升了公司在国际上的知名度和影响力。同年,公司还获得了ISO14001认证,这体现了公司对环境保护的重视和承诺。随着业务的不断拓展,AMOTECH在2006年和2008年分别建立了青岛办公室和韩国第四工厂,进一步提升了公司的产能和效率。

Electro Technik Industries公司的发展小趣事

作为一家具有社会责任感的企业,ETI始终关注环保问题。公司积极推广绿色生产理念,采用环保材料和工艺进行生产。同时,ETI还投入大量资金用于环保设施的建设和运营,减少了对环境的污染。此外,ETI还积极参与社会公益活动,为环保事业贡献自己的力量。这些举措使ETI在业界树立了良好的形象,赢得了社会各界的广泛赞誉。

问答坊 | AI 解惑

早就想参加飞思卡尔技术论坛,这次终于有机会了

做芯片这行好几年,各种技术会议也参加了不少,只是飞思卡尔的技术论坛还没有去过。一直想参加,毕竟属于行业的老大啊!可是哪有那么容易! 今年的飞思卡尔大学生智能车赛开办了一个博客大赛,参与投票的工程师就有机会参加技术论坛。赶紧去投 ...…

查看全部问答>

四川省大学生电子设计竞赛西南科技大学赛区竞赛题目-远程温湿度测量系统

本帖最后由 paulhyde 于 2014-9-15 04:20 编辑 电子竞赛题目-远程温湿度测量系统 一、电子竞赛题目任务: 制作一个远程温湿度测量仪,该测试仪具有温湿度测量和远程显示等功能。其结构框图如下: 二、电子竞赛题目要求: 1、基本要求 ( ...…

查看全部问答>

PB编译项疑问??

请问大家这个PB的编译选择项有什么不同么?之前我编译的时候,修改了一点就要重新编译,一等就是一个小时。我在网上找到一个快速编译的方法,可是这好像只是针对修改了的驱动而言。 所以我有几个疑问,还望大家能帮我解答。 如果我只是增加驱动, ...…

查看全部问答>

关于AGC(Automatic Gain Control)和ADC “100分哦”

请教各位达人,我想找一款内置AGC功能的ADC,ADC最好为12bit,20MSPS 我网络上找了一些资料都没有发现有这样的ADC,许多电路都是内置模拟AGC再加一个ADC来实现的 谁能告诉我有没有这样的ADC啊?有的话提供型号,最好能有PDF文档,立即送100分…

查看全部问答>

modem怎样判断来电是电话还是传真呢

发现不管是电话还是传真 modem收到的都只是RING... 怎样判断到底是电话还是传真呢 谢谢。。…

查看全部问答>

c167CR存储器介绍

C167CR是汽车电子行业应用比较广泛的一种单片机,我正在做相关项目,在这里介绍一下其存储器及外部总线,和大家分享。 (第四点是针对评估板kitCCON-167评估板所作的相关寄存器配置) 1.最大寻址空间是16M 2.片内存储器     &nb ...…

查看全部问答>

转让全新的ARM开发板

因工作繁忙,本人现转让一全新的ARM7开发板:EasyARM2131开发平台 地点:上海市闵行区 电话:13681848395 清单如下: 1.EasyARM2131开发实验板 1 台 2.EasyJTAG-H 1 只 3.SD CARD PACK 1 块 4.杜邦-1P测试线 9 条 5.20P仿真电缆 1 条 6.R ...…

查看全部问答>

STM32的USB2.0的速度可以到多少?12Mor480M?

手册上说: USB 2.0 full speed interface但是文件又说:The STM32F103xC, STM32F103xD and STM32F103xE performance line embed a USBdevice peripheral c ...…

查看全部问答>

运放稳定性

运算放大器的稳定性设计,中文材料,不太清楚在这个论坛里有没有人上传过,要是没有会陆续更新。谢谢~~ 第一部分:环路稳定性基础 第二部分:运放网络、SPICE分析…

查看全部问答>

重油椭圆齿轮流量计

重油椭圆齿轮流量计是一种容积式流量计,测量原理是液体在流量计种流动,在进出口两端会形成差压,在流量计种的椭圆齿轮在轴上不停的旋转,齿轮间的空隙将充满液体,液体随齿轮的旋转被排出,齿轮的转数和流量值成正比关系,测出椭圆齿轮的转数即 ...…

查看全部问答>