【STM8L】STM8L之修正库函数GPIO_WriteBit的Bug

本篇博文最后修改时间:2016年11月18日,02:54。


一、简介

本文修正STM8L的库函数GPIO_WriteBit的Bug


二、实验平台

编译软件:IAR for STM8 1.42.2

硬件平台:stm8l101f3p6开发板

仿真器:ST-LINK

库函数版本:STM8L_STMTouch_Lib_V1.1.0


版权声明

博主:甜甜的大香瓜

声明:喝水不忘挖井人,转载请注明出处。

原文地址:http://blog.csdn.NET/feilusia

联系方式:897503845@qq.com

香瓜BLE之CC2541群:127442605

香瓜BLE之CC2640群:557278427

香瓜BLE之Android群:541462902

香瓜单片机之STM8/STM32群:164311667
甜甜的大香瓜的小店(淘宝店):https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i

四、BUG现象
通过GPIO_WriteBit函数无法控制IO的电平。

五、实验步骤
1、替换GPIO_WriteBit函数(在stm8l10x_gpio.c中)
//******************************************************************************        
//name:             GPIO_WriteBit        
//introduce:        GPIO控制位的函数     
//parameter:        GPIOx: 端口(x = A to D)  
//                  GPIO_Pin: GPIO_Pin_0~GPIO_Pin_7 
//                  GPIO_BitVal: SET or RESET                      
//return:           none      
//author:           甜甜的大香瓜             
//email:            897503845@qq.com         
//QQ group          香瓜单片机之STM8/STM32(164311667)                      
//changetime:       2016.11.18       
//******************************************************************************  
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, BitAction GPIO_BitVal)
{
  /* Check the parameters */
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  assert_param(IS_STATE_VALUE(GPIO_BitVal));

  if (GPIO_BitVal != RESET)
  {
    //SetBit(GPIOx->ODR, GPIO_Pin);//BUG语句,GPIO_Pin是按位来定义的,却被SetBit以字节来操作。
    GPIOx->ODR |= GPIO_Pin;    
  }
  else
  {
    //ClrBit(GPIOx->ODR, GPIO_Pin);//BUG语句,GPIO_Pin是按位来定义的,却被SetBit以字节来操作。
    GPIOx->ODR &= (uint8_t)(~GPIO_Pin);    
  }
}

六、实验结果
将函数修正后,IO口能被正常拉高拉低了。
因此,实验成功。




#include "stm32f10x.h" #include "user_usart.h" uint8_t BUG=0,uart_count=0; uint8_t LEDflag=0; uint8_t RXflag = 0; uint8_t uart_buf[15]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t send_yedata[7]={0x5A,0xA5,0x04,0x80,0x03,0x00,0x00}; /************************************************************************************** * 描 述 : 初始化USART1并配置USART1中断优先级 * 入 参 : 无 * 返回值 : 无 **************************************************************************************/ void USART1_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; USART_ClockInitTypeDef USART_ClockInitStructure; NVIC_InitTypeDef NVIC_InitStructure; //打开所用GPIO及串口1的时钟 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1 , ENABLE); //配置的IO是PA9,串口1的TXD GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure); //配置的IO是PA10,串口1的RXD GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure); //配置串口1的硬件参数 USART_DeInit(USART1); //将外设USART1寄存器重设为缺省值 USART_InitStructure.USART_BaudRate = 38400; //设置串口1波特率为19200 USART_InitStructure.USART_WordLength = USART_WordLength_8b; //设置一个帧中传输数据位 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(USART1, &USART_InitStructure); USART_ClockInitStructure.USART_Clock = USART_Clock_Disable; //时钟低电平活动 USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low; //设置SCLK引脚上时钟输出的极性为低电平 USART_ClockInitStructure.USART_CPHA = USART_CPHA_1Edge; //时钟第一个边沿进行数据捕获 USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable; //最后一位数据的时钟脉冲不从SCLK输出 USART_ClockInit(USART1, &USART_ClockInitStructure); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能USART1接收中断 USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); //使能USART1接收一帧数据中断 USART_Cmd(USART1, ENABLE); //使能USART1外设 //配置串口1中断优先级 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //NVIC_Group:先占优先级2位,从优先级2位 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //配置为串口1中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1; //先占优先级为1 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级为3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断通道 NVIC_Init(&NVIC_InitStructure); } void Send_timedata(char addrH,char addrL,char dataH,char dataL) { unsigned char i=0; unsigned char write_time[8]={0x5A,0XA5,0x05,0x82,0x00,0x00,0x00,0x00}; write_time[4]=addrH; write_time[5]=addrL; write_time[6]=dataH; write_time[7]=dataL; BUG=1; for(i = 0;i<8;i++) { USART_SendData(USART1,write_time[i]); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); Delay(10); } Delay(50); BUG=0; } void Send_page(unsigned char x) { uint8_t i; send_yedata[6]=x; //get_yedata[7]={0x5A,0xA5,0x04,0x80,0x03,0x00,0x00}; for(i = 0;i<7;i++) //将接收到的数据发送 { USART_SendData(USART1, send_yedata[i]); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); Delay(10); } Delay(10); for(i = 0;i<7;i++) //将接收到的数据发送 { USART_SendData(USART1,send_yedata[i]); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); Delay(10); } Delay(1000); } void init_table(void) { int a; for(a=0;a<15;a++) uart_buf[a]=0; } void led_init(void) { //定义IO初始化配置结构体 GPIO_InitTypeDef GPIO_InitStructure; //打开PB端口时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //配置的IO是PB9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //IO口速度为50MHz GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //配置为推挽输出 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //配置IO GPIO_Init(GPIOB, &GPIO_InitStructure); //设置LD2初始化状态为熄灭 GPIO_SetBits(GPIOB,GPIO_Pin_9); } /*************************************************************************** * 描 述 : 点亮LD2 * 参 数 : 无 * 返回值 : 无 ***************************************************************************/ void led_on(void) { //调用库函数GPIO_ResetBits()驱动LED指示灯LD2的引脚(PB9)输出低电平,即点亮LD2 GPIO_ResetBits(GPIOB,GPIO_Pin_9); } /*************************************************************************** * 描 述 : 熄灭LD2 * 参 数 : 无 * 返回值 : 无 ***************************************************************************/ void led_off(void) { //调用库函数GPIO_SetBits()驱动LED指示灯LD2的引脚(PB9)输出高电平,即熄灭LD2 GPIO_SetBits(GPIOB,GPIO_Pin_9); } void Uartdata_process(void) { if((uart_buf[5]==0x18) &&(uart_buf[6]==0x01)) // { if(uart_buf[8]==0x58) { LEDflag=1; } } if((uart_buf[5]==0x18) &&(uart_buf[6]==0x01)) // { if(uart_buf[8]==0x60) { LEDflag=2; } } init_table(); } /************************************************************************************** * 描 述 : USART1全局中断服务 * 入 参 : 无 * 返回值 : 无 **************************************************************************************/ void USART1_IRQHandler(void) { uint8_t clear=clear; uint8_t i; if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)//串口接收一个字节标志 { USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清除USART1的中断待处理位 uart_buf[uart_count++] =USART_ReceiveData(USART1); } else if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET)//串口接收完1帧 { clear=USART1->SR;//先读SR clear=USART1->DR;//再读DR if(uart_buf[0]==0x5A&&uart_buf[1]==0xA5) //帧头有效性判断 { RXflag=1;//主函数读串口数据标志 uart_count=0; //接收数据个数清零 } else //如果传输一帧数据错误,需要将计数清零。 { uart_count=0; } for(i = 0;i<9;i++) //将接收到的数据发送给串口做测试使用。 { USART_SendData(USART1,uart_buf[i]); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); Delay(10); } } } //将上面STM32F103C8T6的串口1程序做端口映射到PB6,PB7。给出完整代码
最新发布
11-19
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

甜甜的大香瓜

谢谢你的支持^_^

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

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

打赏作者

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

抵扣说明:

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

余额充值