打印
[PIC®/AVR®/dsPIC®产品]

攻克PIC18F16Q41的SPI使用方法MCC配置

[复制链接]
10843|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
我这里发现,现在新建工程选择melody的时候会提示不支持,不知道为何,后续再研究咋回事,之前是可以的。本次我使用的是Classic版本。仔细阅读手册,PIC18F16Q41的SPI的SCK和SDI引脚是固定的,不可随意胡乱更改,需要按照手册指定可用的选择,否在会导致SDO输出的时序有误。

而MCC里面是可以随意选择引脚的,这应该是我之前无法正常使用SPI硬件接口的根本原因。
而Classic生成的代码有一些缺陷需要自己补充完善。
本次我驱动WS2812B,将SPI时钟配置为8Mhz
然后晚上SPI发送函数,如下所示:
void SPI1_WriteByte(uint8_t byte)
{
    SPI1TCNTL = 1;
    SPI1CON2 = (SPI1CON2 & ~(_SPI1CON2_SPI1RXR_MASK)) | (_SPI1CON2_SPI1TXR_MASK);
    SPI1TXB = byte;
    while(!PIR3bits.SPI1TXIF);
}
这样该函数就只会响应发送完成标志了。
#include "mcc_generated_files/mcc.h"

typedef struct COLOR
{
    uint8_t redChannel;
    uint8_t greenChannel;
    uint8_t blueChannel;
} color_t;

void ws2812_send(unsigned char x)
{
    for(int i=0;i<8;i++)
    {
        x<<=i;
        if(x&0x80)
        {
            SPI1_WriteByte(0xF8);
        }
        else
        {
            SPI1_WriteByte(0xC0);
        }
    }
}

void WriteNeopixel(color_t color)
{
    ws2812_send(color.greenChannel);   
    ws2812_send(color.redChannel);   
    ws2812_send(color.blueChannel);

}

    color_t neopixelsBuffer[20] = {

        { 64, 100, 64 }, { 64, 64,  0 }, {  0, 64, 64 }, {  0, 64,  0 },

        { 64,  0, 64 }, { 64,  0,  0 }, {  0,  0, 64 }, {  30,  10,  2 },

        { 96, 96, 96 }, { 48, 48, 48 }, { 24, 24, 24 }, { 12, 24, 12 },

        {  36,  36,  6 }, {  3,  33,  33 }, {  16,  16,  1 }, {  50,  0,  0 },

        {  6,  60,  6 }, {  3,  3,  30 }, {  10,  1,  10 }, {  0,  10,  0 }

    };

void main(void)
{
    // Initialize the device
    SYSTEM_Initialize();

    // If using interrupts in PIC18 High/Low Priority Mode you need to enable the Global High and Low Interrupts
    // If using interrupts in PIC Mid-Range Compatibility Mode you need to enable the Global Interrupts
    // Use the following macros to:

    // Enable the Global Interrupts
    //INTERRUPT_GlobalInterruptEnable();

    // Disable the Global Interrupts
    //INTERRUPT_GlobalInterruptDisable();

    SPI1_Open(SPI1_DEFAULT);  
    __delay_ms(1000);
    for(int i=0;i<20;i++) WriteNeopixel(neopixelsBuffer[i]);
   
    while (1)
    {
        
    }
}
/**
End of File
*/
引脚的配置如下:
0
有图为证





使用特权

评论回复
沙发
lklklklklk0519| | 2024-8-6 16:06 | 只看该作者
very good!

使用特权

评论回复
板凳
AloneKaven| | 2024-8-15 23:39 | 只看该作者
这个灯亮度高吗

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:西安公路研究院南京院
简介:主要工作从事监控网络与通信网络设计,以及从事基于嵌入式的通信与控制设备研发。擅长单片机嵌入式系统物联网设备开发,音频功放电路开发。

1961

主题

15931

帖子

208

粉丝