STM32开发基础代码

本文详细介绍了C语言中的一些基础代码片段,包括宏定义、GPIO接口操作、IIC通信、位运算、数据类型转换、字符串处理、串口3DMA接收设置以及中断服务函数。
摘要由CSDN通过智能技术生成

 基础代码一(宏定义等)

#define Max(a,b)  (a>b)?a:b   //带参宏  宏仅是简单的字符串替换 不涉及到变量类型  参数可以是表达式
//且通常带括号 参数需要括号 某个情况下整个表达式也需要括号


#define SDA_IN()       {GPIOB->CRL&=0XF0FFFFFF;GPIOB->CRL|=0X08000000;GPIOB->BSRR=(1<<6);} //SDA设置为上拉输入模式
#define SDA_OUT()      {GPIOB->CRL&=0XF0FFFFFF;GPIOB->CRL|=0X03000000;}                    //SDA设置为推免输出模式
#define READ_SDA        GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_6)       //读取SDA 
#define IIC_SDA_OUT(x)  GPIO_WriteBit(GPIOB, GPIO_Pin_6, (BitAction)x) //设置SDA电平
#define RESET_IO(x)    GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)x)  //PA4控制WiFi的复位 

#define  IIC_SCL_H    GPIO_SetBits(GPIOB, GPIO_Pin_5)    //SCL拉高
#define  IIC_SDA_H    GPIO_SetBits(GPIOB, GPIO_Pin_6)    //SDA拉高

#define  IIC_SCL_L    GPIO_ResetBits(GPIOB, GPIO_Pin_5)  //SCL拉低
#define  IIC_SDA_L    GPIO_ResetBits(GPIOB, GPIO_Pin_6)  //SDA拉低

按位异或赋值 (^=)
示例:
i = 0x00;
i ^= 0x01;
第一次执行结果为 i = 1
第二次执行结果为 i = 0
以此类推

long int Data_group;
float Data_F;
Data_group=Data_high<<24|Data_mid2<<16|Data_mid1<<8|Data_low;
Data_F = *((float*)&Data_group);//将long int 数据转换为float数据 再取值赋给Data_F

*(float *) 和 (float *)的区别
//(float *) 类型强转
//前者先转成float*指针,然后取指针指向的值 ,后者是转换为float*指针
//float * 表示这是一个float指针,而在指针前面再加*就表示这个指针所指变量。
//所以*(float *)就是一个float变量

#define WK_UP PAin(0)  //PA0 定义该引脚输入
#define WK_UP   GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读取按键3(WK_UP)
#define B_dn() GPIO_SetBits(GPIOA,GPIO_Pin_5)//该引脚置高
#define B_up() GPIO_ResetBits(GPIOA,GPIO_Pin_5)//该引脚置低

//带参宏,可以像内联函数一样使用,输出高电平或低电平
#define DHT11_DATA_OUT(a)  if (a)  \
          GPIO_SetBits(GPIOB,D11_PIN);\
          else    \
          GPIO_ResetBits(GPIOB,D11_PIN)
 //读取引脚的电平
#define  DHT11_DATA_IN()     GPIO_ReadInputDataBit(GPIOB,D11_PIN)

typedef enum{
  NET_S,
  NET_N,
  NET_F,
  NET_G,
}E_NUM_STATUS;//定义状态变量 全大写 不赋初值则默认从0开始依次递加 只赋首个元素初值,其他依次递加

strx = strstr((const char*)Usart1RecBuf,(const char*)"OK");//
//Strstr是C语言中的函数,作用是返回字符串中首次出现子串的地址
//将字符1变为数字1的方法 '1'-'0'即可

PPM = PPM >= 99? 99: PPM;// 该表达式的含义为当PPM大于等于99时,取99,否则取他本身,并赋值给他自己

strx = strstr((const char*)Usart1RecBuf,(const char*)"SEND OK");
//用于获取sendOK在Usart1RecBuf中的首地址。既可以用于判断Usart1RecBuf中是否含有sendOK
strchr()函数功能为在一个串中查找给定字符的第一个匹配之处

char temp_buf[20];
float Temp_nub;
sprintf(temp_buf,"{temperatrue=%.2f}",Temp_nub);

u8 x,y,i,j;//ij为图片的尺寸 x,y(1~8)为图片上顶点坐标
OLED_DrawBMP(x,y/8,48+i,6+j/8,Light_icon);

#define SDA_DATA(a)  if (a)  \
              GPIO_SetBits(GPIOB,GPIO_Pin_11);\
              else    \
              GPIO_ResetBits(GPIOB,GPIO_Pin_11)

int main()//strcpy的用法
{
   char src[40];
   char dest[100];
  
   memset(dest, '\0', sizeof(dest));
   strcpy(src, "This is runoob.com");
   strcpy(dest, src);
   memcmp(&MQTT_CMDOutPtr[1],CMD2,strlen(CMD2))
   //原型为 int memcmp(const void *str1, const void *str2, size_t n));
   //其功能是把存储区 str1 和存储区 str2 的前 n 个字节进行比较。该函数是按字节比较的,位于string.h
   //如果返回值 < 0,则表示 str1 小于 str2。
  //如果返回值 > 0,则表示 str2 小于 str1。
  //如果返回值 = 0,则表示 str1 等于 str2。
   printf("最终的目标字符串: %s\n", dest);
   
   return(0);
}
//原型:extern char *strcat(char *dest,char *src);
//用法:#include <string.h>
//功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的’\0’)并添加’\0’。
//说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
//返回指向dest的指针。
    char d[20]="Golden Global";
    char *s=" View";
    clrscr();
    strcat(d,s);
    printf("%s",d);

(360-fabs(navi-Deal[7])>165)&&(360-fabs(navi-Deal[7])<195)&&flag_i==0)
//两次的航向角差值大于165小于195时停止转弯操作左右两个边各15°余量
//用于判断角度在360内的变化量

基础代码二(10转16进制)

u8 motor_su[9] = {0xa1,0xac,0x11};//看数据手册上的定义,这里是瞎写的
void trans_1(u16 x){//unsigned short int
  //x为目标值
  u32 data;//unsigned int
  u8 i;
  u8 sign; 
    data = x*1000/80;//速度型。位置型需要更改公式
    if((data&0x80000000)>0){//判断符号 若满足则为负数
    //0x80000000 的二进制位 原码 1000 0000 0000 0000 0000 0000 0000 0000
      motor_su[3] = 0xFF;
      motor_su[4] = 0xFF;
    }
    else{
      motor_su[3] = 0x00;
      motor_su[4] = 0x00;
    }
  motor_su[6]=data&0x000000ff;//取末位字节
  motor_su[5]=(data&0x0000ffff)/256;//取倒数第二位字节

  for(i=0;i<7;i++){
    sign +=motor_su[i];
  }
  motor_su[7] = sign&0xff;//取最后一字节
}

基础代码三(串口3DMA接数据设置模板)


#define  USART3_RXBUF_SIZE    40    // USART3接收缓存长度
uint8_t  USART3_RxBuffer[USART3_RXBUF_SIZE];   // USART3接收数据缓存
//uint8_t  USART3_TxBuffer[USART3_TXBUF_SIZE];   // USART3发送数据缓存
__IO uint16_t USART3_RxLen;
u8 u3_RxBuffer[USART3_RXBUF_SIZE];//导航数据缓存空间 DMA接收地址
//模式控制

void GPIO_init_usart3(){

  GPIO_InitTypeDef  GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  USART_InitTypeDef USART_InitStructure;
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  //使能USART1,GPIOA时钟
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);//使能GPIOA,D时钟

  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;         //PD7端口配置
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      //推挽输出
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(GPIOD, &GPIO_InitStructure);
  //USART1_TX   GPIOA.9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PA.9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOA.9
   
  //USART1_RX    GPIOA.10初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PA10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOA.10  

   USART_InitStructure.USART_BaudRate = 115200;          //波特率115200
   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_Init(USART3, &USART_InitStructure);            //配置串口参数函
   USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);                  //使能空闲中断  
   USART_DMACmd(USART3,USART_DMAReq_Rx,ENABLE);//使能串口DMA接收功能
   USART_Cmd(USART3, ENABLE);   // 使能USARTx   
  
  NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;    //子优先级3
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;      //IRQ通道使能
  NVIC_Init(&NVIC_InitStructure);  //根据指定的参数初始化VIC寄存器
  
  RS485_TX_EN=0;
}


void DMA_Receive_init(DMA_Channel_TypeDef*DMA_CHx,u32 usart,u32 buffer,u16 len)//仅用于配置串口的DMA接收功能
{
  DMA_InitTypeDef DMA_Initstructure;
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2,ENABLE);
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
  
  DMA_Cmd(DMA_CHx,DISABLE);
  DMA_DeInit(DMA_CHx);
  //DMA_Initstructure.DMA_PeripheralBaseAddr=(u32)(&UART4->DR);
  DMA_Initstructure.DMA_PeripheralBaseAddr=(u32)usart;
  //DMA_Initstructure.DMA_MemoryBaseAddr=(u32)u4_RxBuffer;
  DMA_Initstructure.DMA_MemoryBaseAddr=(u32)buffer;
  DMA_Initstructure.DMA_DIR=DMA_DIR_PeripheralSRC;
  DMA_Initstructure.DMA_BufferSize=len;
  DMA_Initstructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
  DMA_Initstructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
  DMA_Initstructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
  DMA_Initstructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
  DMA_Initstructure.DMA_Mode=DMA_Mode_Normal;
  DMA_Initstructure.DMA_Priority=DMA_Priority_High;
  DMA_Initstructure.DMA_M2M=DMA_M2M_Disable;
  DMA_Init(DMA_CHx,&DMA_Initstructure);
  DMA_ClearFlag(DMA2_FLAG_GL3);
  DMA_ClearFlag(DMA1_FLAG_GL3);
  DMA_Cmd(DMA_CHx,ENABLE);
}
void USART3_Receive_Data(u8 *buf,u8 *len)//在程序中判断接收到的字节时,使用本函数将接收到的数据传入待判断数组
{
  u8 rxlen=USART3_RxLen;
  u8 i=0;
  *len=0;        //默认为0
  delay_ms(5);    //等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束
  if(rxlen==USART3_RxLen&&rxlen)//接收到了数据,且接收完成了
  {
    for(i=0;i<rxlen;i++)
    {
      buf[i]=USART3_RxBuffer[i];  
    }    
    *len=USART3_RxLen;  //记录本次数据长度
    USART3_RxLen=0;    //清零
  }
}
void USART3_IRQHandler(void)//DMA接收时的中断服务函数
{
  u8 i;
  if(USART_GetITStatus(USART3,USART_IT_IDLE)!=RESET)
  {
    DMA_Cmd(DMA1_Channel3,DISABLE);//串口3 rx对应通道DMA1-3  tx对应DMA1-2
    i=USART3->SR;
    i=USART3->DR;
    USART3_RxLen=USART3_RXBUF_SIZE-DMA_GetCurrDataCounter(DMA1_Channel3);
    if(USART3_RxLen!=0)
    {
      for(i=0;i<USART3_RxLen;i++)
      {
        USART3_RxBuffer[i]=u3_RxBuffer[i];
      }
      for(i=0;i<USART3_RxLen;i++)
      {
        u3_RxBuffer[i]=0;
      }
    }
    USART_ClearFlag(USART3,USART_FLAG_IDLE);
    DMA_SetCurrDataCounter(DMA1_Channel3,USART3_RXBUF_SIZE);
    DMA_Cmd(DMA1_Channel3,ENABLE);
  }
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UH_SZJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值