OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3436|回复: 1

STM32xx 系列使用笔记快来码住

[复制链接]

221

主题

221

帖子

0

精华

高级会员

Rank: 4

积分
762
金钱
762
注册时间
2021-5-18
在线时间
28 小时
发表于 2021-10-28 15:33:11 | 显示全部楼层 |阅读模式
1、获取定时器时钟频率

uint32_t get_time_clock_freq(TIM_TypeDef *t) {
    uint32_t time_clock_freq = 0;
    RCC_ClocksTypeDef clocks;
    RCC_GetClocksFreq(&clocks);
    if(t == TIM1 || t == TIM8) {
        time_clock_freq = clocks.PCLK2_Frequency;
        if(clocks.HCLK_Frequency/clocks.PCLK2_Frequency > 1) {
            time_clock_freq <<= 1;
        }
    } else {
        time_clock_freq = clocks.PCLK1_Frequency;
        if(clocks.HCLK_Frequency/clocks.PCLK1_Frequency > 1) {
            time_clock_freq <<= 1;
        }
    }
    return time_clock_freq;
}

2、ADC通道对应关系
1.png

3、中断优先级
2.jpg

4、ADC采样计算
3.png

5、DMA
DMA用在什么地方合适?形象地说,DMA是MCU内的搬运工,通过DMA把数据从外设和内存之间的自动搬迁,节省软件的开销。

STM32 的DMA有三种模式:内存-外设,外设-内存,内存-内存。

举几个例子:

USART串口发送:没DMA的情况,要发送大量数据,需要每一个字节发送后产生完成中断或轮询旗标,然后软件介入把下一个数据放入TDR寄存器,这样会有大量中断或等待消耗程序的资源,如果采用DMA的话,至需要预先在DMA通道设定要发送的数据的第一字节的内存地址(例如: &buf[0]), 和设定需要发送多少字节,开始发送后,DMA就会像z指针一样完成一节,指针自动递增或减自动移动数据到发送寄存器,直至发送完成会有一次中断通知。中间过程软件完全可以不介入。

ADC采集:多次采样或循环采样,同样地没DMA的话,采样完毕中断,搬移ADC的采样值,出现大量中断,如果是高速采样情况更甚。可以通过DMA采样完成后自动写入你指定的数组地址,一个循环后DMA一个完成中断通知你做后续的事情,例如平均算法之类的。

DAC波形输出:把波形的样本建立一个数组,使用DMA循环发送。

用和不用当然都可以发送。不用DMA发送是需要单片机实时参与,由单片机一个一个地发送数据并进行监控。但是如果用DMA,设置了起始地址,数据大小等参数后,就直接由专门的一个DMA模块进行数据发送,发送过程中单片机无需参与。发送完后会产生中断告知单片机。由此可知用DMA可以节省单片机资源,让单片可以在同一时间里干更多事。

6、I2C通讯(软件I2C)
在添加I2C设备的时候,读取数据时候,主机需要返回ACK给从机,但是得注意主机返回ACK最后需要释放 SDA线,在以前使用的过程中,遇到过没有释放也可以成功的例子。
但是最近在使用STM32L051添加欧姆龙 D6T-1A-02非接触温度传感器的时候遇到,如果不在返回ACK后释放SDA线控制权,从机无法正常发送数据(因为SDA先被主机拉低了,从机无法拉高):

void IIC_Ack(void)
{
        MYIIC_CLK_LOW;    //SCL为低,SDA为低,SCL为高,SDA为低,应答低电平有效,SCL为低,产生应答信号
        // MYSDA_OUT;
        MYIIC_DATA_LOW;
        delay_us(10);
        MYIIC_CLK_HIGH;
        delay_us(10);
        MYIIC_CLK_LOW;
        /*注意,加上了下面一句,释放总线,数据才正确*/
        delay_us(10);
        MYIIC_DATA_HIGH;
}

7、HAL库中的串口操作
使用STMCubeMX生成工程后,会自动设置好NVIC中断优先级,使能了NVIC中断,在usart.c下的`void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)中有:

HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);

但是串口的接收中断,是没有自动使能的,我们需要自己使能,但是如何使能,比如:

/*USART_Enocean_BUF , USART_RX_BUF 是你的接收缓冲区*/
HAL_UART_Receive_IT(&hlpuart1, USART_Enocean_BUF, 1);
HAL_UART_Receive_IT(&huart2, USART_RX_BUF, 1);

如果你需要接收一帧数据,可以开启IDLE中断,初始化后,运行前加上
__HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE);
那么还有一句:
__HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);
这句话是不是开启了前面的HAL_UART_Receive_IT就不需要用了呢?
实际上测试是这么回事,以前在标准库中使用串口通讯UART_IT_RXNE基本上都必须使能的,那么为什么?
(待更新)

8、中断操作
屏蔽外部中断
关闭中断
EXTI->IMR &= ~(EXTI_Linex);
打开中断
EXTI->IMR |= EXTI_Linex;

原文链接:http://bj.dyrs.com.cn/story/202110/1164506

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

14

主题

821

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2106
金钱
2106
注册时间
2021-7-17
在线时间
659 小时
发表于 2021-10-28 15:55:46 | 显示全部楼层
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-9 13:48

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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