你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

谁能总结下这段代码的功能吗

[复制链接]
lulululu2018 提问时间:2018-5-6 15:53 /
想问一下 我对这段代码总结的功能对不对;
电脑通过串口助手发送数据给单片机
单片机接收数据进入接收数据串口中断
读取DR寄存器中接收到的数据
再通过串口回写给电脑


以下是程序代码:
文件:mian.c
//功能:串口初始化、打开定时器中断,然后一直接收数据状态就好了。发送在中断中实现
#include "stm32f10x.h"
#include "usart.h"
u8 USART_rx_data;
int main(void)
{
  
  RCC_Configuration();      //系统时钟配置
  GPIO_Configuration();      //端口初始化
  NVIC_Configuration();      //中断源配置
  USART_Configuration();     //串口1初始化
  Time_Init();            //定时器初始化
  #ifdef DEBUG
      debug();
  #endif
  TIM_Cmd(TIM3,ENABLE);
   while(1)
   {
   }
}
文件:usart.c
#include "stm32f10x.h"
#include "stdio.h"
#include "usart.h"
  unsigned char auchCRCHi [256] ={
  0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
  0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
  0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
  0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
  0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
  0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
  0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
  0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
  0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
  0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
  0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
  0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
  0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
  0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
  0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
  0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40};
  unsigned char auchCRCLo [256] ={
  0x00,0xC0,0xC1,0x01,0xC3,0x03,0x02,0xC2,0xC6,0x06,0x07,0xC7,0x05,0xC5,0xC4,0x04,
  0xCC,0x0C,0x0D,0xCD,0x0F,0xCF,0xCE,0x0E,0x0A,0xCA,0xCB,0x0B,0xC9,0x09,0x08,0xC8,
  0xD8,0x18,0x19,0xD9,0x1B,0xDB,0xDA,0x1A,0x1E,0xDE,0xDF,0x1F,0xDD,0x1D,0x1C,0xDC,
  0x14,0xD4,0xD5,0x15,0xD7,0x17,0x16,0xD6,0xD2,0x12,0x13,0xD3,0x11,0xD1,0xD0,0x10,
  0xF0,0x30,0x31,0xF1,0x33,0xF3,0xF2,0x32,0x36,0xF6,0xF7,0x37,0xF5,0x35,0x34,0xF4,
  0x3C,0xFC,0xFD,0x3D,0xFF,0x3F,0x3E,0xFE,0xFA,0x3A,0x3B,0xFB,0x39,0xF9,0xF8,0x38,
  0x28,0xE8,0xE9,0x29,0xEB,0x2B,0x2A,0xEA,0xEE,0x2E,0x2F,0xEF,0x2D,0xED,0xEC,0x2C,
  0xE4,0x24,0x25,0xE5,0x27,0xE7,0xE6,0x26,0x22,0xE2,0xE3,0x23,0xE1,0x21,0x20,0xE0,
  0xA0,0x60,0x61,0xA1,0x63,0xA3,0xA2,0x62,0x66,0xA6,0xA7,0x67,0xA5,0x65,0x64,0xA4,
  0x6C,0xAC,0xAD,0x6D,0xAF,0x6F,0x6E,0xAE,0xAA,0x6A,0x6B,0xAB,0x69,0xA9,0xA8,0x68,
  0x78,0xB8,0xB9,0x79,0xBB,0x7B,0x7A,0xBA,0xBE,0x7E,0x7F,0xBF,0x7D,0xBD,0xBC,0x7C,
  0xB4,0x74,0x75,0xB5,0x77,0xB7,0xB6,0x76,0x72,0xB2,0xB3,0x73,0xB1,0x71,0x70,0xB0,
  0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92,0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,
  0x9C,0x5C,0x5D,0x9D,0x5F,0x9F,0x9E,0x5E,0x5A,0x9A,0x9B,0x5B,0x99,0x59,0x58,0x98,
  0x88,0x48,0x49,0x89,0x4B,0x8B,0x8A,0x4A,0x4E,0x8E,0x8F,0x4F,0x8D,0x4D,0x4C,0x8C,
  0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,0x43,0x83,0x41,0x81,0x80,0x40};

unsigned short CRC16(unsigned char* puchMsg, unsigned short usDataLen)
{

  unsigned char uchCRCHi = 0xFF ;
  unsigned char uchCRCLo = 0xFF ;
  unsigned char uIndex ;
  while (usDataLen--)
  {
    uIndex = uchCRCHi^*puchMsg++;
    uchCRCHi = uchCRCLo^auchCRCHi[uIndex];
    uchCRCLo = auchCRCLo[uIndex];
  }
  return (uchCRCHi << 8 | uchCRCLo) ;
}

void RCC_Configuration(void)
{
  ErrorStatus HSEStartUpStatus;      //枚举变量,定义高速时钟的启动状态
  RCC_DeInit();              //RCC系统重置,用于Debug目的
  RCC_HSEConfig(RCC_HSE_ON);          //使能高速时钟源HSE  
  HSEStartUpStatus = RCC_WaitForHSEStartUp();    //等待HSE稳定
  if(HSEStartUpStatus == SUCCESS)
  {
    FLASH_SetLatency(FLASH_Latency_2);     
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);     
   
    RCC_HCLKConfig(RCC_SYSCLK_Div1);         // HCLK = SYSCLK
    RCC_PCLK2Config(RCC_HCLK_Div1);          // PCLK2 = HCLK
    RCC_PCLK1Config(RCC_HCLK_Div2);         ///PCLK1 = HCLK/2

    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
    RCC_PLLCmd(ENABLE);
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){}
   
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    while(RCC_GetSYSCLKSource() != 0x08){}
  }
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 |RCC_APB2Periph_GPIOA |RCC_APB2Periph_AFIO |RCC_APB2Periph_GPIOB , ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
}
//------------------------------------------------------------------
//函数名:void GPIO_Configuration()
//输入参数:null
//返回参数:null
//说明:GPIO初始化函数
//------------------------------------------------------------------
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;     //GPIO初始化结构体声明


  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;       //USART1 TX
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  GPIO_Init(GPIOA, &GPIO_InitStructure);           //A端口

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;       //USART1 RX
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //复用浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);         //A端口
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
//------------------------------------------------------------------
//函数名:void NVIC_Configuration()
//输入参数:null
//返回参数:null
//说明:NVIC初始化函数
//------------------------------------------------------------------
void NVIC_Configuration(void)
{              
  NVIC_InitTypeDef NVIC_InitStructure;       //NVIC初始化结构体声明

  #ifdef VECT_TAB_RAM      
   
    NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); //如果程序在RAM中调试那么定义中断向量表在RAM中否则在Flash中
  #else
   
    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);  
  #endif
   
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  //设置串口1中断
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级 0
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;    //子优先级为0
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     //使能
  NVIC_Init(&NVIC_InitStructure);
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;    //设置定时器3全局中断
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //抢占优先级 1
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;   //子优先级为0
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     //使能
  NVIC_Init(&NVIC_InitStructure);
}
//------------------------------------------------------------------
//函数名:void USART_Configuration()
//输入参数:null
//返回参数:null
//说明:串口初始化函数
//------------------------------------------------------------------
void USART_Configuration(void){
    USART_InitTypeDef USART_InitStructure;     //串口初始化结构体声明
  USART_ClockInitTypeDef USART_ClockInitStruct;
  USART_InitStructure.USART_BaudRate = 115200;      //设置波特率为115200bps
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;  //数据位8位
  USART_InitStructure.USART_StopBits = USART_StopBits_1;   //停止位1位
  USART_InitStructure.USART_Parity = USART_Parity_No;    //无校验位 USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;   //无硬件流控
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //接受和发送模式都打开
  USART_ClockInitStruct.USART_Clock=USART_Clock_Disable; //串口时钟禁止
  USART_ClockInitStruct.USART_CPOL=USART_CPOL_Low;    //数据低电平有效
  USART_ClockInitStruct.USART_CPHA=USART_CPHA_2Edge;   //配置CPHA使数据在第2个边沿的时候被捕获
  USART_ClockInitStruct.USART_LastBit=USART_LastBit_Disable;  // 禁用最后一位,使对应的时钟脉冲不会再输出到SCLK引脚
  USART_ClockInit(USART1, &USART_ClockInitStruct);//配置USART与时钟相关的设置
  USART_Init(USART1, &USART_InitStructure);       //配置串口参数函数
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);     //使能接收中断
//USART_ITConfig(USART1, USART_IT_TXE, ENABLE);    //使能发送缓冲空中断
//USART_ITConfig(USART1, USART_IT_TC, ENABLE);    //使能发送完成中断
  USART_ClearFlag(USART1,USART_FLAG_TC);       //清除发送完成标志位
  USART_Cmd(USART1, ENABLE);         //使能串口1
}
//------------------------------------------------------------------
//函数名:void Time_Init()
//输入参数:null
//返回参数:null
//说明:定时器初始化函数
//------------------------------------------------------------------
void Time_Init(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_DeInit(TIM3);            //复位TIM3定时器
  TIM_TimeBaseStructure.TIM_Period =7999; //设置自动重装载寄存器锁存值,1ms溢出      
  TIM_TimeBaseStructure.TIM_Prescaler = 8;      //9分频
  TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;      //时钟分频因子           
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器向上计数模式                     
  
  TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);    //写TIM3各寄存器参数
  TIM_ClearFlag(TIM3,TIM_FLAG_Update);
  TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
}
文件:usart.h
#ifndef _USART_H
#define _USART_H
#include
#include "stm32f10x.h"

void RCC_Configuration(void);   //声明RCC初始化函数
void GPIO_Configuration(void);   //声明GPIO初始化函数
void NVIC_Configuration(void);   //声明NVIC初始化函数
void USART_Configuration(void);   //声明串口初始化函数
void Time_Init(void);     //声明定时器初始化函数
unsigned short CRC16(unsigned char* puchMsg, unsigned short usDataLen);
#endif
文件:stm32f103x_it.c
//需要设置串口接收中断和定时器3中断,中断时间为1ms
//------------------------------------------------------------------
//函数名:void USART1_IRQHandler(void)
//输入参数:null
//返回参数:null
//说明:串口接收中断服务
//------------------------------------------------------------------
void USART1_IRQHandler(void)
{
  
  if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //判断读寄存器是否非空
  {      
//    GPIO_SetBits(GPIOB,GPIO_Pin_6);
    rx_data[RbufCounter++]=USART_ReceiveData(USART1);//接收字节到接收缓冲区
    if(USART_Rsv_Status==0)
    {
      if(RbufCounter>1)
      {
        if(rx_data[0]==0xA5&&rx_data[1]==0x5A)    //当接收到的数据帧头两个字节同时为0xA5和0x5A时
        {
          USART_Rsv_Status=1;
//           USART_SendData(USART1, rx_data[0]);
        }
        else
        {
          rx_data[0]=rx_data[1];
          RbufCounter=1;
         
        }
      }
    }
    else
    {
      USART_1ms_Cnt=0;
    }               
  }         
}
//------------------------------------------------------------------
//函数名:void TIM2_IRQHandler(void)
//输入参数:null
//返回参数:null
//说明:定时器2中断服务
//------------------------------------------------------------------
void TIM2_IRQHandler(void)
{
}
//------------------------------------------------------------------
//函数名:void TIM3_IRQHandler(void)
//输入参数:null
//返回参数:null
//说明:定时器3中断服务
//------------------------------------------------------------------
void TIM3_IRQHandler(void)
{
  if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)//判断是否为定时器3溢出中断
  {
   
    GPIO_SetBits(GPIOB,GPIO_Pin_6);
    TIM_ClearITPendingBit(TIM3, TIM_IT_Update);  //清中断标记
    if(USART_Rsv_Status==1)
    USART_1ms_Cnt++;
    if(USART_1ms_Cnt>5)     
    {
//      USART_SendData(USART1,0xAA);
      USART_Rsv_Status=0;     //连续计数超过5次对USART_Rsv_Status置0,继续等待接收
      USART_1ms_Cnt=0;  //当USART_1ms_Cnt>5时对USART_1ms_Cnt重新清零
      if(RbufCounter==(u16)rx_data[4]+7)   //检验数据的完整性
      {
         int i;     //定义循环变量
        int j;
        data_length=rx_data[4];
        for(i=0;i
        {
          data=rx_data;
        }
        CRC_data_Hi=rx_data[RbufCounter-1];
        CRC_data_Lo=rx_data[RbufCounter-2];
        CRC_data=CRC16((unsigned char*)data,data_length+5);
        CRC_data_Hi1=CRC_data>>8;
        CRC_data_Lo1=CRC_data&0x00ff;
         if(CRC_data_Hi==(u8)CRC_data_Hi1 && CRC_data_Lo==CRC_data_Lo1)
         {
           for(j=0;rx_data[j]!='\0';j++)//循环逐字输出,到结束字'\0'
           {      
             USART_SendData(USART1, rx_data[j]); //发送字符
        

收藏 评论6 发布时间:2018-5-6 15:53

举报

6个回答
wenyangzeng 回答时间:2018-5-6 16:34:23
本帖最后由 wenyangzeng 于 2018-5-6 16:38 编辑

楼主自己下载到板子上试试,Debug就知道了。

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

与龙共舞 回答时间:2018-5-6 17:10:11
1 有可能是自己串口发的 TIM3就是在发  那就不debug了 不用USB-ttl看PC串口
在watch看  自己发给自己
2只处理5A A5 开头的报文

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

feixiang20 回答时间:2018-5-6 23:39:34
针对每一段,你分别检验一下,最好实际做下

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

五哥1 回答时间:2018-5-7 01:27:32
弄个带屏幕的板子看

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

butterflyspring 回答时间:2018-5-7 10:55:56
RCC_DeInit();              //RCC系统重置,用于Debug目的

这个不是,其他的,我看不下去了,,这么长,其他人接力..

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

天空.~~ 回答时间:2018-6-11 12:22:24
串口接收数据,以0x5a,oxa5 开头的,并会将接收的数据进行CRC计数校验数据.

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版