layout: post
title: 3月份日志
categories: 日志
tags:
- 开发
- 日志
BGImage: 'https://github.xutongxin.me/https://raw.githubusercontent.com/xutongxin1/PictureBed/master/img0/202020210312152426.png'
jekyll-theme-WuK:
musicid: '526464671'
3.9
继续开工
先弄弄DMA
(uint8_t *)t
将变量类型强制转换为uint8 *类型
volatile uint8_t rx_len ; //接收一帧数据的长度
volatile关键词影响编译器编译的结果,用volatile声明的变量表示该变量随时可能发生变化,与该变量有关的运算,不要进行编译优化,以免出错
USART的中断类型比你想象的要多
UART_IT_CTS:CTS更改中断
UART_IT_LBD:LIN中断检测中断
UART_IT_TXE:发送数据寄存器为空中断
UART_IT_TC:发送完成中断
UART_IT_RXNE:接收数据寄存器不为空中断
UART_IT_IDLE:空闲线检测中断(接收完之后的中断等,一般不会触发)
UART_IT_PE:奇偶校验错误中断
UART_IT_ERR:错误中断(帧错误,噪声错误,溢出错误)
开启语句
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //启动IDLE中断
全局变量办法
在一个头文件先定义
//user.h
#ifndef DMA_USER_H
#define DMA_USER_H
extern uint8_t rx_buffer[100];
#endif //DMA_USER_H
然后在main.c的main()外面声明
//main.h
//需要先#include "user.h"
/* USER CODE BEGIN PV */
uint8_t rx_buffer[100];
/* USER CODE END PV */
然后该项目所有文件直接引用user.h即可
3.15
3.11
USART串口几个中断的问题
接收有两种方案,中断来接收和DMA转存
前者使用
//HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size),如
HAL_UART_Receive_IT(&huart1,(uint8_t *)&value,1); //中断接收一个字符,存储到value中
这句话不仅定义了要收个数据去pData里,还定义了要收到一个一个字符就中断一次(后台),并且存到pData,直到存了Size个字符,结束中断转存,进入回调函数
HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); //串口接收中断回调函数
这里的逻辑有些复杂,再详细说说
比如我现在有100个字符
我打开了
HAL_UART_Receive_IT(&huart1,(uint8_t *)&value,20);//只要20个
收到第一个就会进入
HAL_UART_IRQHandler(UART_HandleTypeDef *huart); //串口中断处理函数
然后存到value里去,然后算算数,才收了一个还没到20个呢,然后继续等着下一个
等到20个字符了,不会再进HAL_UART_IRQHandler中断的同时,进入HAL_UART_RxCpltCallback回调函数,记住,此时HAL_UART_Receive_IT已经完成了,所以要继续收剩下80个记得开回来。
和HAL_UART_RxCpltCallback类似的回调函数有以下函数
HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); //串口发送中断回调函数
HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart); //串口发送一半中断回调函数(用的较少)
HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); //串口接收中断回调函数
HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);//串口接收一半回调函数(用的较少)
HAL_UART_ErrorCallback();//串口接收错误函数
但是每次都进中断并不太好,性能不是最优的,所以有了DMA
DMA是啥不说了,DMA需要配置
HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
还是把数据放进pData,然后收Size个数据
但是不同的是这个不经过中断,因此更快占用更小
先附上和DMA有关的函数
HAL_UART_Transmit_DMA();//串口DMA模式发送
HAL_UART_Transmit_DMA();//串口DMA模式接收
HAL_UART_DMAPause() //暂停串口DMA
HAL_UART_DMAResume(); //恢复串口DMA
HAL_UART_DMAStop();// 结束串口DMA
突然又有个问题了,如果我不确定我要收多少怎么办
第一种不用DMA的老办法
HAL_UART_Receive_IT(&huart1,(uint8_t *)&value,1); //每次收一个!
然后在中断里等待自己设置的终止符
这个方法慢,所以有了第二种
等待串口接收到东西后的休息时间
先在main.h初始化变量
volatile uint8_t rx_len = 0; //接收一帧数据的长度
volatile uint8_t recv_end_flag = 0; //一帧数据接收完成标志
uint8_t rx_buffer[200]={0}; //接收数据缓存
#define BUFFER_SIZE 255
修改static void MX_USART1_UART_Init(void)函数,或者在main.c里添加
//main.c
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //启动串口收完数据后的闲时中断(开了自己不会默认停下)
HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);//打开第一次接收
然后跳进
//stm32f1xx_it.c中
void USART1_IRQHandler(void);
如果你是开HAL_UART_Receive_IT,其实每个数据转存都会进来这里
然后你要做的就是加多这个函数内要干的事情
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
uint32_t tmp_flag = 0;
uint32_t temp;
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);//这段默认就在这里了,不要删去
//最好上面的逻辑也换个地方写
/* USER CODE BEGIN USART1_IRQn 1 */
tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位
if((tmp_flag != RESET))//idle标志还在,串口没有突然又干活了
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位
//HAL_UART_DMAStop(&huart2); //先暂停
//temp = __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);// 获取DMA中未传输的数据个
//rx_len = BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个
//recv_end_flag=1;//引入flag方便主while处理数据
//DO What You Want To DO
HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);//重置size的计数!
}
/* USER CODE END USART1_IRQn 1 */
}
最后是DMA发送
HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
其他的发送虽然从此看不上了,但还是记录一下
HAL_UART_Transmit();//串口发送数据,使用超时管理机制
HAL_UART_Receive();//串口接收数据,使用超时管理机制
HAL_UART_Transmit_IT();//串口中断模式发送
HAL_UART_Receive_IT();//串口中断模式接收
最后还看到个有意思的代码
/* * 函数功能: 重定向c库函数printf到DEBUG_USARTx
* 输入参数: 无
* 返 回 值: 无
* 说 明:无
*/
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
/**
* 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx
* 输入参数: 无
* 返 回 值: 无
* 说 明:无
*/
int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
return ch;
}
两个没有用DMA的,但是还是可以的
尝试造esp8266的无线调试器,模块用的是Esp-wroom-02d,记录几个点
-
EN脚理论上其实不是直接上电,而是加一个延时电路
-
烧录时GPIO15和GPIO0都要拉低,但是运行时GPIO0置空,GPIO15似乎还是要拉低
-
烧录命令可以在构建完之后看到,GUI版本的烧录器没有验证(Flash容量没得选)
如:python "C:\Users\xtx\OneDrive - xutongxin\ESP8266\DAP\pytool\esptool\esptool.py" -p COM16 -b 921600 --after hard_reset write_flash --flash_mode dio --flash_size 16MB --flash_freq 80m 0x0 bootloader.bin 0x8000 partition-table.bin 0x10000 esp8266_dap.bin
-
esptool可以直接用rtos-sdk里的,pip直接安装不太好用。同时要先装pip install pyserical
-
bootloader.bin和partition-table.bin也在rtos-sdk里,直接在Github Action提取出来即可
然后是Github Action功能,就是在线构建功能
- 如果直接按着main.yml对着ubuntu虚拟机这样做是不行的,所以不能线下复现
- 提取出文件的方案(记得重新校对排版),然后在action界面可以看到
- name: Deliver firmware
uses: actions/upload-artifact@v2
with:
name: pytool
path: ./ESP8266_RTOS_SDK/components/esptool_py
- name: Deliver firmware1
uses: actions/upload-artifact@v2
with:
name: pytool2
path: ./idf.py
至于利用发布功能提取文件就算了吧