rt-thread应用笔记--CAN设备


/// 打开设备
int can_init(void)
{    
    rt_err_t res;
    rt_thread_t thread;    
    can_dev = rt_device_find("can1");     /// 查找 CAN 设备
    if (!can_dev)
    {
        rt_kprintf("find %s failed!\n", "can1");
        return RT_ERROR;
    }
    /// 初始化信号量用于接收
    rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);    
    /// 打开设备(中断接收及中断发送)
    res = rt_device_open(can_dev, RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_INT_RX);
    RT_ASSERT(res == RT_EOK);    
    /// 创建数据接收线程
    thread = rt_thread_create("can_rx", can_rx_thread, RT_NULL, 1024, 25, 10);
    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
    }
    else
    {
        rt_kprintf("create can_rx thread failed!\n");
    }
    return res;
}

发送数据

int can_send(int id, char* buff, int len)
{
    int i;
    int ret;    
    struct rt_can_msg msg;   
    
    msg.id  = id;              
    msg.ide = RT_CAN_STDID;    // 标准帧
    msg.rtr = RT_CAN_DTR;      // 数据帧
    msg.len = len;             // 数据长度    
    for(i = 0; i < len; i++)
    {
        msg.data[i] = *buff++;
    }    
    ret = rt_device_write(can_dev, 0, &msg, sizeof(msg));
    if (ret == 0)
    {
        rt_kprintf("can dev write data failed!\n");
    } 
    return ret;
}

- 阅读全文 -

rt-thread应用笔记--I2C设备


#define AT24C_ADDR  0x50    /// 注意这里是7bit地址
static struct rt_i2c_bus_device *at24c_dev = RT_NULL;

初始化设备:

void at24c_init(void)
{    
    /// 查找i2c总线
    at24c_dev = (void*)rt_device_find("i2c1");
    if(at24c_dev != RT_NULL)
    {
        rt_kprintf("i2c bus1 is found\r\n");      
    }
    else
    {
        rt_kprintf("i2c bus1 not found\r\n");  
    }     
}

读取数据:

int at24c_read(int addr, void *pdata,  int len)
{
    int ret;
    struct rt_i2c_msg msg[2];
    if(at24c_dev == RT_NULL)
    {
        return -1;
    }    
    msg[0].addr  = AT24C_ADDR;
    msg[0].flags = RT_I2C_WR;
    msg[0].buf   = (void*)&addr;
    msg[0].len   = 1;    
    
    msg[1].addr  = AT24C_ADDR;
    msg[1].flags = RT_I2C_RD;
    msg[1].buf   = pdata;
    msg[1].len   = len;
    
    ret = rt_i2c_transfer(at24c_dev, msg, 2); 
    if(ret == 2)
    {
        return 0;
    }
    else
    {
        return -1;
    }      
}

写操作:

int at24c_write_page(int addr, void *pdat, int len)

{
    rt_uint8_t buff[40];
    struct rt_i2c_msg msg;
    buff[0] = addr;
    rt_memcpy(&buff[1], pdat, len);    
    msg.addr  = AT24C_ADDR;
    msg.flags = RT_I2C_WR;
    msg.buf   = buff;
    msg.len   = len + 1;    
    if(rt_i2c_transfer(at24c_dev, &msg, 1) == 1)
    {
        return RT_EOK;
    }
    else
    {
        return RT_ERROR;
    }      
}
/// 写操作,需要进行分页处理
int at24c_write(int addr, void *pdat, int len)
{
    int wlen;
    char *p = pdat;
    if(at24c_dev == RT_NULL)
    {
        return -1;
    }
    while(len > 0)
    {
        wlen = 8 - (addr & 0x07);
        if(wlen > len)
        {
            wlen = len;
        }         
        at24c_write_page(addr, p, wlen);
        delayms(10);
        len  -= wlen;        
        addr += wlen;
        p    += wlen;         
    }        
    return 0;
}

添加I2C总线 修改board/Kconfig添加以下代码

 menuconfig BSP_USING_I2C1
        bool "Enable I2C1 BUS (software simulation)"
        default n
        select RT_USING_I2C
        select RT_USING_I2C_BITOPS
        select RT_USING_PIN
        if BSP_USING_I2C1
            config BSP_I2C1_SCL_PIN
                int "i2c1 scl pin number"
                range 1 100
                default 22
            config BSP_I2C1_SDA_PIN
                int "I2C1 sda pin number"
                range 1 100
                default 23
        endif

即可用menuconfig来配置


改进版的配置:

menuconfig BSP_USING_I2C
    bool "Enable I2C"
    select RT_USING_I2C
    select RT_USING_I2C_BITOPS
    default n
    if BSP_USING_I2C
        config BSP_USING_I2C1
            bool "Enable I2C1 BUS (software simulation)"
            default n               
            select RT_USING_PIN
            if BSP_USING_I2C1
                config BSP_I2C1_SCL_PIN
                    int "i2c1 scl pin number"
                    range 1 100
                    default 22
                config BSP_I2C1_SDA_PIN
                    int "I2C1 sda pin number"
                    range 1 100
                    default 23
        endif
        config BSP_USING_I2C2
            bool "Enable I2C2 BUS (software simulation)"
            default n
            select RT_USING_PIN
            if BSP_USING_I2C2
                config BSP_I2C2_SCL_PIN
                    int "i2c2 scl pin number"
                    range 1 100
                    default 48
                config BSP_I2C2_SDA_PIN
                    int "I2C2 sda pin number"
                    range 1 100
                    default 49
            endif
    endif

- 阅读全文 -

rt-thread应用笔记--系统搭建及配置


目录说明:
bsp - 板级支持包位于 bsp 目录中,并对各大厂商进行发分类,开发板及用户自定义的BSP均在此;
libcpu - 主要是针对不同架构的CPU的相关文件,普通用户一般不需要修改

配置选项:

$ menuconfig

更新工程: 可选mdk4,mkd5,iar

 $ scons --target=mdk5

只添加/删除rt-thread的文件,不更改用户的文件及application目录中的main文件。

修改模版默认项:
直接双击打开模版,修改完成关闭即可
Debug页面修改为ST-Link下载器
Flash Download 页面使能 Reset and Run
Pack页面取消 Enable选项

- 阅读全文 -

QT5开发笔记--pdf输出


QT += printsupport

方案一:

QPrinter pr(QPrinter::HighResolution);      /// 高分辨率
pr.setPageSize(QPrinter::A4);               /// A4纸张
pr.setResolution(300);                      /// 设置分辨率
pr.setOutputFormat(QPrinter::PdfFormat);    /// 设置打印机格式PDF
pr.setOutputFileName("D:\\test.pdf");       /// 设置导出pdf路径

QPainter painter;           /// 创建画笔,以QPainter作为画板
painter.begin(&pr);         /// 关联输出    
QFont font;
font.setBold(true);         /// 加粗字体
font.setFamily("仿宋");      /// 设置字体
font.setPointSize(20);      /// 设置字号
painter.setFont(font);
painter.drawText(1100,100,"输出模版");

QPen pen;
pen.setColor(QColor(100,150,255));
pen.setWidth(5);
painter.setPen(pen);
painter.drawLine(0,200,2300,200);   /// 画横线


QPixmap pixmap = QPixmap("d:\\01.png");
painter.drawPixmap(300,500, pixmap);    /// 输出图片
QImage img = QImage("d:\\01.png");
painter.drawImage(500,300,img);

painter.end();  /// 结束

方案二:

QFile pdfFile("D:\\test3.pdf");
pdfFile.open(QIODevice::WriteOnly);
QPdfWriter pdfWriter(&pdfFile);
pdfWriter.setPageSize(QPagedPaintDevice::A4);   /// 设置纸张
pdfWriter.setResolution(300);                   /// 分辨率决定了相像素数

QPainter painter(&pdfWriter);
QFont font;
font.setBold(true);         /// 加粗字体
font.setFamily("仿宋");      /// 设置字体
font.setPointSize(10);      /// 设置字号
painter.setFont(font);
painter.drawText(0,1200,"1234567");

QPen pen;
pen.setColor(QColor(100,150,255));
pen.setWidth(5);
painter.setPen(pen);
painter.drawRect(0,0,2400,3430);    /// 画框

A4尺寸为 8.27英寸x11.69英寸(210mm×297mm)
300dpi表示每英寸300像素,A4为2480x3508,
左边距及上边距各保留了设置为40像素(不可用),右边距及下边距也保留对应尺寸,
则实际可用尺寸为 = 2400 x3428

A4:2400 x 3428
A5:(1754 - 80)x(2480 - 80) --> (1674x2400)

- 阅读全文 -

STM32应用笔记--通过DMA发送串口数据


1.将发送数据写入队列
2.如果传输标志为0,则启动直接启动传输(更新标志为1);
3.捕捉DMA传输完成中断,在中断中查看是否有数据要发送
4.如果无数据发送,则设置DMA传输标志为0


初始化DMA:

/// UART1发送位于通道4的数据流7
__HAL_RCC_DMA2_CLK_ENABLE();                            /// 使能DMA时钟
hdma1.Instance                 = DMA2_Stream7;          /// Stream7表示UART发送
hdma1.Init.Channel             = DMA_CHANNEL_4;         /// 通道4
hdma1.Init.Direction           = DMA_MEMORY_TO_PERIPH;  /// 方向: 存储器-->外设
hdma1.Init.PeriphInc           = DMA_PINC_DISABLE;
hdma1.Init.MemInc              = DMA_MINC_ENABLE;
hdma1.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma1.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
hdma1.Init.Mode                = DMA_NORMAL;
hdma1.Init.Priority            = DMA_PRIORITY_LOW;
hdma1.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma1) != HAL_OK)
{
  
}    
__HAL_LINKDMA(huart, hdmatx, hdma1);   /// 关联usart句柄

DMA发送:

HAL_DMA_Start(huart1.hdmatx,
              (uint32_t)dma_buff, 
              (uint32_t)&huart1.Instance->DR, 
              sp);                         // 开启 DMA 传输
huart1.Instance->CR3 |= USART_CR3_DMAT;    // 使能串口 DMA 发送

- 阅读全文 -


Copyright©2024 春天花会开, All Rights Reserved. Email: webmaster@oroct.com