首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LibOpenCM3 1-通过UART DMA STM32F1的导线

LibOpenCM3 1-通过UART DMA STM32F1的导线
EN

Stack Overflow用户
提问于 2020-04-14 05:00:46
回答 2查看 382关注 0票数 0

我刚刚开始使用STM32F103和FreeRTOS + Libopencm3来理解嵌入式世界(在Arduino、RPi等之后)。我的第一个挑战是将DS18B20温度传感器连接到我的微处理器上。1-Wire总线非常容易理解,但不支持本地支持,所以我遵循了您的建议,并使用了带DMA的UART上的1-wire。

DS18B20有关于USART2TX (+4k7上拉+二极管)和USART2RX的数据,VCC到5V和GND。

1-Wire初始化:

代码语言:javascript
复制
static void ow_init(void)
{
    // One-Wire
    // Already done : rcc_periph_clock_enable(RCC_GPIOA);
    gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART2_TX);
    gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO_USART2_RX);
    usart_set_baudrate(USART2, 115200);
    usart_set_databits(USART2, 8);
    usart_set_stopbits(USART2, USART_STOPBITS_1);
    usart_set_mode(USART2, USART_MODE_TX);
    usart_set_parity(USART2, USART_PARITY_NONE);
    usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);
    usart_enable(USART2);

    rcc_periph_clock_enable(RCC_DMA1);
}

1-导线复位:

代码语言:javascript
复制
uint8_t ow_reset(void)
{
    usart_disable_rx_dma(USART2);
    usart_disable_tx_dma(USART2);

    usart_set_baudrate(USART2, 9600);
    usart_set_databits(USART2, 8);
    usart_set_stopbits(USART2, USART_STOPBITS_1);
    usart_set_mode(USART2, USART_MODE_TX);
    usart_set_parity(USART2, USART_PARITY_NONE);
    usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);

    usart_send(USART2, 0xf0);
    while(usart_get_flag(USART2, USART_SR_TC));
    uint8_t ow_presence;
    ow_presence = usart_recv(USART2);

    usart_set_baudrate(USART2, 115200);
    usart_set_databits(USART2, 8);
    usart_set_stopbits(USART2, USART_STOPBITS_1);
    usart_set_mode(USART2, USART_MODE_TX_RX);
    usart_set_parity(USART2, USART_PARITY_NONE);
    usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);

    if(ow_presence != 0xf0)
    {
        return 1;
    }

    return 0;
}

使用以下命令获取便签簿:

代码语言:javascript
复制
void ow_convert_to_scratchpad(void)
{
    const uint8_t convert_T[] = {0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,  // 0xCC
                                 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00}; // 0x44

    dma_channel_reset(DMA1, DMA_CHANNEL7);
    dma_set_peripheral_address(DMA1, DMA_CHANNEL7, (uint32_t)&USART2_DR);
    dma_set_memory_address(DMA1, DMA_CHANNEL7, (uint32_t) convert_T);
    dma_set_number_of_data(DMA1, DMA_CHANNEL7, sizeof(convert_T));
    dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL7);
    dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL7);
    dma_set_peripheral_size(DMA1, DMA_CHANNEL7, DMA_CCR_PSIZE_8BIT);
    dma_set_memory_size(DMA1, DMA_CHANNEL7, DMA_CCR_MSIZE_8BIT);
    dma_set_priority(DMA1, DMA_CHANNEL7, DMA_CCR_PL_LOW);

    dma_enable_channel(DMA1, DMA_CHANNEL7);
    usart_enable_tx_dma(USART2);
}

uint16_t ow_get_scratchpad(void)
{
    const uint8_t read_scratch[] = {0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,  // 0xCC
                                    0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF,  // 0xBE
                                    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                                    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

    uint8_t buf[8];

    dma_channel_reset(DMA1, DMA_CHANNEL6);
    dma_set_peripheral_address(DMA1, DMA_CHANNEL6, (uint32_t)&USART2_DR);
    dma_set_memory_address(DMA1, DMA_CHANNEL6, (uint32_t) buf);
    dma_set_read_from_peripheral(DMA1, DMA_CHANNEL6);
    dma_set_number_of_data(DMA1, DMA_CHANNEL6, sizeof(read_scratch));
    dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL6);
    dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL6);
    dma_set_peripheral_size(DMA1, DMA_CHANNEL6, DMA_CCR_PSIZE_8BIT);
    dma_set_memory_size(DMA1, DMA_CHANNEL6, DMA_CCR_MSIZE_8BIT);
    dma_set_priority(DMA1, DMA_CHANNEL6, DMA_CCR_PL_LOW);

    dma_channel_reset(DMA1, DMA_CHANNEL7);
    dma_set_peripheral_address(DMA1, DMA_CHANNEL7, (uint32_t)&USART2_DR);
    dma_set_memory_address(DMA1, DMA_CHANNEL7, (uint32_t) read_scratch);
    dma_set_number_of_data(DMA1, DMA_CHANNEL7, sizeof(read_scratch));
    dma_set_read_from_peripheral(DMA1, DMA_CHANNEL6);
    dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL7);
    dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL7);
    dma_set_peripheral_size(DMA1, DMA_CHANNEL7, DMA_CCR_PSIZE_8BIT);
    dma_set_memory_size(DMA1, DMA_CHANNEL7, DMA_CCR_MSIZE_8BIT);
    dma_set_priority(DMA1, DMA_CHANNEL7, DMA_CCR_PL_LOW);

    dma_enable_channel(DMA1, DMA_CHANNEL6);
    dma_enable_channel(DMA1, DMA_CHANNEL7);
    usart_enable_tx_dma(USART2);
    usart_enable_rx_dma(USART2);

    while(dma_get_interrupt_flag(DMA1, DMA_CHANNEL6, DMA_TCIF));

    uint16_t tt = 0;

    for(int i=0;i<32; i++)
    {
        uart1_printf("Bit : %d \n\r", buf[i]);
        if(buf[i] == 0xff)
        {
            tt = (tt >> 1) | 0x8000;
        }
        else
        {
            tt = tt >> 1;
        }
    }
    return tt;
}

static void demo_task(void *args)
{

    (void)args;

    for (;;) {
        uart1_printf("Hello\n\r");
        uint8_t p = ow_reset();
        uart1_printf("presence = %d\n\r", p);
        ow_convert_to_scratchpad();
        for(int i=0; i<5000000; i++)
        {
            __asm__("nop");
        }
        ow_reset();
        uint16_t t = ow_get_scratchpad();
        uart1_printf("t = %d \n\r", t);
        vTaskDelay(pdMS_TO_TICKS(500));
    }
}

最后是尝试到达DS18B20的任务

代码语言:javascript
复制
static void demo_task(void *args)
{

    (void)args;

    for (;;) {
        ow_reset();
        ow_convert_to_scratchpad();
        vTaskDelay(pdMS_TO_TICKS(500));
        ow_reset();
        uint16_t t = ow_get_scratchpad();
        uart1_printf("t = %d \n\r", t);
        vTaskDelay(pdMS_TO_TICKS(500));
    }
}

我收到一些位,如0xCC、0xBE、0xFF,但没有更多的应答。

EN

回答 2

Stack Overflow用户

发布于 2020-04-15 04:36:49

好的,那么

代码语言:javascript
复制
rcc_periph_clock_enable(RCC_USART2);

失踪了所以USART2不能做它的工作。我现在可以发送和接收数据了。

除了这一行(它会无限期地等待)外,重置函数仍然有效:

代码语言:javascript
复制
while(usart_get_flag(USART2, USART_SR_TC));

我不明白为什么当传输完成时这个标志不是真的...但是我在RX线路上有0x00,所以我认为传感器正在响应(我希望...)

我使用DMA的函数ow_convert_to_scratchpad看起来像是阻塞的。我不知道为什么..。

我只是试着(为了好玩...)通过硬编码发送的0xCC、0x44、0xCC、0xBE和来自传感器的已读但无应答(0x00)来替换整个DMA。

票数 0
EN

Stack Overflow用户

发布于 2020-05-21 11:32:48

我来派对有点晚了,但是...你有没有先试过一些不那么复杂的东西?(我的意思是检查起来更简单)

比如问一个DS18B20它的地址?

代码语言:javascript
复制
Reset bus and check presence.
Send search ROM cmd (write byte 0xF0)
loop 64 times reading address bits from LSB to MSB {
   read bit i
   read bit i complement
   check they are 1 and 0 or the other way around
   send bit i back to device so it sends you back the next bit
}

最后是设备地址的8个字节。1字节族0x28 48位地址1字节CRC8检查整件是否正确。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61196677

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档