找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4084|回复: 1
打印 上一主题 下一主题
收起左侧

2018年全国电子设计大赛(吉林赛区)B题程序源码

[复制链接]
跳转到指定楼层
楼主
ID:328014 发表于 2018-9-14 03:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
2018年全国电子设计大赛(吉林赛区)B题程序源码基于STM32F103ZET6,圆盘悬吊装置8路PWM输出定时器,编码器测速,陀螺仪

单片机源程序如下:
  1. #include "touch_key.h"
  2. #include "SysTick.h"
  3. #include "usart.h"

  4. #define Touch_ARR_MAX_VAL 0xffff  //最大的ARR值       
  5. u16 touch_default_val=0;  //为按下触摸按键时的值

  6. /*******************************************************************************
  7. * 函 数 名         : TIM5_CH2_Input_Init
  8. * 函数功能                   : TIM5_CH2输入捕获初始化函数
  9. * 输    入         : arr:自动重装载值
  10.                                          psc:预分频系数
  11. * 输    出         : 无
  12. *******************************************************************************/
  13. void TIM5_CH2_Input_Init(u16 arr,u16 psc)
  14. {
  15.         TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
  16.         TIM_ICInitTypeDef TIM_ICInitStructure;
  17.         GPIO_InitTypeDef GPIO_InitStructure;
  18.        
  19.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  20.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);//使能TIM5时钟
  21.        
  22.        
  23.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;                          
  24.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;          //浮空输入模式
  25.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //IO口速度为50MHz
  26.         GPIO_Init(GPIOA, &GPIO_InitStructure);                                  // PA0
  27.        
  28.        
  29.         TIM_TimeBaseInitStructure.TIM_Period=arr;   //自动装载值
  30.         TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //分频系数
  31.         TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
  32.         TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式
  33.         TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStructure);       
  34.        
  35.         TIM_ICInitStructure.TIM_Channel=TIM_Channel_2; //通道2
  36.         TIM_ICInitStructure.TIM_ICFilter=0x00;  //滤波
  37.         TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//捕获极性
  38.         TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1; //分频系数
  39.         TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;//直接映射到TI1
  40.         TIM_ICInit(TIM5,&TIM_ICInitStructure);
  41.                
  42.         TIM_Cmd(TIM5,ENABLE); //使能定时器
  43. }

  44. /*******************************************************************************
  45. * 函 数 名         : Touch_Reset
  46. * 函数功能                   : 触摸按键复位 先放电然后充电并释放计时器内的值
  47. * 输    入         : 无
  48. * 输    出         : 无
  49. *******************************************************************************/
  50. void Touch_Reset(void)
  51. {
  52.         GPIO_InitTypeDef GPIO_InitStructure;
  53.        
  54.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;                          
  55.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          //推挽输出模式
  56.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //IO口速度为50MHz
  57.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  58.          
  59.         GPIO_ResetBits(GPIOA,GPIO_Pin_0);//输出0,放电

  60.         delay_ms(5);
  61.         TIM_ClearFlag(TIM5, TIM_FLAG_CC2|TIM_FLAG_Update); //清除标志
  62.         TIM_SetCounter(TIM5,0);                //归0
  63.        
  64.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;          //浮空输入模式       
  65.         GPIO_Init(GPIOA, &GPIO_InitStructure);
  66. }

  67. /*******************************************************************************
  68. * 函 数 名         : Touch_Get_Val
  69. * 函数功能                   : 返回捕获高电平值
  70. * 输    入         : 无
  71. * 输    出         : 捕获高电平值
  72. *******************************************************************************/
  73. u16 Touch_Get_Val(void)
  74. {
  75.         Touch_Reset();
  76.         while(TIM_GetFlagStatus(TIM5,TIM_FLAG_CC2)==0) //等待捕获到高电平标志
  77.         {
  78.                 if(TIM_GetCounter(TIM5)>Touch_ARR_MAX_VAL-500)  //超时了直接返回CNT值
  79.                 {
  80.                         return TIM_GetCounter(TIM5);
  81.                 }
  82.         }
  83.         return TIM_GetCapture2(TIM5); //返回捕获高电平值
  84. }

  85. /*******************************************************************************
  86. * 函 数 名         : Touch_Key_Init
  87. * 函数功能                   : 触摸按键初始化
  88. * 输    入         : 无
  89. * 输    出         : 0:正常
  90.                                          1:不正常
  91. *******************************************************************************/
  92. u8 Touch_Key_Init(u8 psc)  
  93. {
  94.         u8 i;
  95.         u16 buf[10];
  96.         u8 j;
  97.         u16 temp;
  98.         TIM5_CH2_Input_Init(Touch_ARR_MAX_VAL,psc);
  99.        
  100.         for(i=0;i<10;i++) //读取10次为按下时候的触摸值
  101.         {
  102.                 buf[i]=Touch_Get_Val();
  103.                 delay_ms(10);
  104.         }
  105.        
  106.         for(i=0;i<9;i++)   //从小到大排序
  107.         {
  108.                 for(j=i+1;j<10;j++)
  109.                 {
  110.                         if(buf[i]>buf[j])
  111.                         {
  112.                                 temp=buf[i];
  113.                                 buf[j]=buf[j];
  114.                                 buf[j]=temp;
  115.                         }
  116.                 }
  117.         }
  118.        
  119.         temp=0;
  120.         for(i=2;i<8;i++)  //取中间6个数值求和 取其平均数
  121.         {
  122.                 temp+=buf[i];
  123.         }
  124.         touch_default_val=temp/6;
  125.         printf("touch_default_val=%d \r\n",touch_default_val);
  126.         if(touch_default_val>Touch_ARR_MAX_VAL/2)
  127.         {
  128.                 return 1;//初始化遇到超过Touch_ARR_MAX_VAL/2的数值,不正常!
  129.         }
  130.         return 0;
  131. }

  132. /*******************************************************************************
  133. * 函 数 名         : Touch_Get_MaxVal
  134. * 函数功能                   : 读取n次,取最大值
  135. * 输    入         : n:连续获取的次数
  136. * 输    出         : n次读数里面读到的最大读数值
  137. *******************************************************************************/
  138. u16 Touch_Get_MaxVal(u8 n)
  139. {
  140.         u16 temp=0;
  141.         u16 res=0;
  142.         while(n--)
  143.         {
  144.                 temp=Touch_Get_Val();//得到一次值
  145.                 if(temp>res)res=temp;
  146.         }
  147.         return res;
  148. }  

  149. /*******************************************************************************
  150. * 函 数 名         : Touch_Key_Scan
  151. * 函数功能                   : 触摸按键扫描
  152. * 输    入         : 0:不支持连续触发(按下一次必须松开才能按下一次)
  153.                                          1:支持连续触发(可以一直按下)
  154. * 输    出         : 0:没有按下
  155.                                          1:有按下
  156. *******************************************************************************/                                                                                  
  157. #define TOUCH_GATE_VAL         100        //触摸的门限值,也就是必须大于tpad_default_val+TOUCH_GATE_VAL,才认为是有效触摸.
  158. u8 Touch_Key_Scan(u8 mode)
  159. {
  160.         static u8 keyen=0;        //0,可以开始检测;>0,还不能开始检测         
  161.         u8 res=0;
  162.         u8 sample=3;                //默认采样次数为3次         
  163.         u16 rval;
  164.         if(mode)
  165.         {
  166.                 sample=6;        //支持连按的时候,设置采样次数为6次
  167.                 keyen=0;        //支持连按          
  168.         }
  169.         rval=Touch_Get_MaxVal(sample);
  170.         if(rval>(touch_default_val+TOUCH_GATE_VAL)&&rval<(10*touch_default_val))//大于touch_default_val+TPAD_GATE_VAL,且小于10倍touch_default_val,则有效
  171.         {                                                         
  172.                 if((keyen==0)&&(rval>(touch_default_val+TOUCH_GATE_VAL)))        //大于touch_default_val+TOUCH_GATE_VAL,有效
  173.                 {
  174.                         res=1;
  175.                 }          
  176.                 printf("触摸后捕获高电平值为:%d\r\n",rval);                                                                           
  177.                 keyen=3;                                //至少要再过3次之后才能按键有效   
  178. ……………………

  179. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
光电门测速.rar (547.93 KB, 下载次数: 14)
chengxu.rar (455.96 KB, 下载次数: 14)


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:328014 发表于 2018-9-14 04:02 | 只看该作者
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表