gpt4 book ai didi

c - SPI 电子墨水显示器与 PIC 18F46K22 接口(interface)的问题

转载 作者:行者123 更新时间:2023-12-04 08:21:00 25 4
gpt4 key购买 nike

我正在使用 PIC 18F46K22在 SPI 主模式下与 Waveshare 1.54" ePaper Module 通信. FOSC 频率为 8Mhz 内部,SPI 配置为 FOSC/4。因此,当我检查逻辑分析仪上的输出时,一些输出位与预期不同。 SCL有一些偏差。
enter image description here

#include <xc.h>
#include "config.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "main.h"

//#define _XTAL_FREQ 8000000
#define SPI1_DUMMY_DATA 0x0
#define SPI_RX_IN_PROGRESS 0x0
#define MY_BUFFER_SIZE 25

extern UBYTE EPD_Init(const unsigned char* lut);


unsigned char myWriteBuffer[100]="Hi I'm master..";
uint8_t myReadBuffer[100];
uint8_t total;
uint8_t temp;
uint8_t my_data = 0x58;

void UART_Init(void)
{
//69
SPBRG2 = 69;

TXSTA2bits.BRGH = 1;
BAUDCON2bits.BRG16 = 1; // Divisor at 8 bit

TRISDbits.TRISD6 = 0;
TRISDbits.TRISD7 = 1;

RCSTA2bits.SPEN = 1; // Enable serial port
TXSTA2bits.SYNC = 0; // Async operation

TXSTA2bits.TX9 = 0; // No tx of 9th bit
RCSTA2bits.RX9 = 0; // No rx of 9th bit

TXSTA2bits.TXEN = 1; // Enable transmitter
RCSTA2bits.CREN = 1; // Enable receiver
}

void UART_Putch(unsigned char bt)
{
while (!PIR3bits.TX2IF); // hold the program till TX buffer is free
TXREG2 = bt; //Load the transmitter buffer with the received value
}

void UART_Print(unsigned const char *ptr)
{
while (*ptr != 0)
{
UART_Putch(*ptr++);
}
}

unsigned char UART_getch() {
unsigned char temp;
if (RCSTA2bits.OERR) // check for Error
{
RCSTA2bits.CREN = 0; //If error -> Reset
//__delay_ms(10);
RCSTA2bits.CREN = 1; //If error -> Reset
}
while (!PIR3bits.RC2IF); // hold the program till RX buffer is free

temp = RCREG2;
return temp; //receive the value and send it to main function
}

void main()
{
ANSELA = 0;
ANSELB = 0;
ANSELC = 0;
ANSELD = 0;

TRISBbits.TRISB0 = 0; //RST Pin OUTPUT
TRISBbits.TRISB1 = 0; //DC Pin OUTPUT
TRISBbits.TRISB2 = 0; //CS Pin OUTPUT

TRISBbits.RB3 = 1; //BUSY Pin INPUT

// int i;

TRISD =0;/* PORT initialize as output */

EPD_RST_PIN = 0;
EPD_DC_PIN = 0;

//OSCCON = 0x72; /* Use internal osc. frequency 16 MHz */

OSCCONbits.SCS = 0b10; //Frequency & PLL SETUP
OSCCONbits.IRCF = 0b110; //8 MHz
while (!OSCCONbits.HFIOFS);

OSCTUNEbits.PLLEN = 0; //PLL disable


UART_Init();



SPI_Init_Master(); /* Initialize SPI communication as a master */



if(EPD_Init(lut_full_update) != 0) {
UART_Print("e-Paper init failed\r\n");
while(1);
}
UART_Print("e-Paper init\r\n");
for(uint8_t i = 0; i < 10; i++){
__delay_ms(10);
}


EPD_Clear();
UART_Print("e-Paper cleared\r\n");
for(uint8_t i = 0; i < 10; i++){
__delay_ms(50);
}


while(1)
{



// total = 0;
// //do
// //{
// LATAbits.LATA5=0;
// //total = SPI1_Exchange8bitBuffer(SPI1_DUMMY_DATA, MY_BUFFER_SIZE, &myReadBuffer[total]);
// total = SPI1_Exchange8bit(my_data);
//
// LATAbits.LATA5=1;
// __delay_ms(500);
// __delay_ms(500);
// // Do something else...
//
// //} while(total < MY_BUFFER_SIZE);
// //while(1);
//
// EPD_Clear();
//
// __delay_ms(500);
}
}

void SPI_Init_Master()
{
/* PORT definition for SPI pins*/
TRISCbits.TRISC4 = 1; /* RB0 as input(SDI) */
TRISCbits.TRISC3 = 0; /* RB1 as output(SCK) */
// TRISBbits.TRISB2 = 0; /* RA5 as a output(SS') */
TRISCbits.TRISC5 = 0; /* RC7 as output(SDO) */

/* To initialize SPI Communication configure following Register*/
EPD_CS_PIN = 1;
SSP1STAT=0x00; /* Data change on rising edge of clk , BF=0*/
SSP1CON1=0x20; /* Slave mode,Serial enable, idle state high for clk */
PIR1bits.SSP1IF=0;
/* Disable the ADC channel which are on for multiplexed pin
when used as an input */
ADCON0=0; /* This is for de-multiplexed the SCL
and SDI from analog pins*/
ADCON1=0x0F; /* This makes all pins as digital I/O */
}

uint8_t SPI1_Exchange8bit(uint8_t data)
{
// Clear the Write Collision flag, to allow writing
SSP1CON1bits.WCOL = 0;

SSP1BUF = data;

while(SSP1STATbits.BF == SPI_RX_IN_PROGRESS)
{
}

return (SSP1BUF);
}

uint8_t SPI1_Exchange8bitBuffer(uint8_t *dataIn, uint8_t bufLen, uint8_t *dataOut)
{
uint8_t bytesWritten = 0;

if(bufLen != 0)
{
if(dataIn != NULL)
{
while(bytesWritten < bufLen)
{
if(dataOut == NULL)
{
SPI1_Exchange8bit(dataIn[bytesWritten]);
}
else
{
dataOut[bytesWritten] = SPI1_Exchange8bit(dataIn[bytesWritten]);
}

bytesWritten++;
}
}
else
{
if(dataOut != NULL)
{
while(bytesWritten < bufLen )
{
temp = SPI1_Exchange8bit(SPI1_DUMMY_DATA);

if(temp!=SPI1_DUMMY_DATA)
{
UART_Putch(temp); //uart print
dataOut[bytesWritten] = temp;
bytesWritten++;
}
__delay_ms(5);
}
}
}
}

return bytesWritten;
}

最佳答案

将您的逻辑分析仪 SCK 和 MOSI 时序与 https://www.waveshare.com/wiki/1.54inch_e-Paper_Module 中为部件指定的时序进行比较:
enter image description here
请注意,MOSI (SDIN) 状态必须在 SCK (SCLK) 的上升沿保持稳定。在您的情况下,MOSI 转换与上升沿同步,并且您在 MOSI 具有正确的 D7=0 状态之前有一个时钟转换。 SPI 时序由时钟极性和时钟相位定义 - 提供四种可能的时钟模式。将 Waveshare 时序图与 18F46K22 datasheet 进行比较:
enter image description here
Waveshare 图表明可以使用 CKP=1/CKE=0 或 CKP=0/CKE=1,您有:

SSP1STAT=0x00 ;
SSP1CON1=0x20 ;
这是 CKP=0/CKE=0 (与您的逻辑分析仪跟踪相关)。
您需要以下任一:
SSP1STAT=0x20 ; // CKE=1
SSP1CON1=0x20 ; // CKP=0
或者
SSP1STAT=0x00 ; // CKE=0
SSP1CON1=0x30 ; // CKP=1
由于 SCK 的空闲状态(由 CKP 控制)是无关紧要的,我建议保持原样并使用第一个建议 - 这似乎更直观。
另请注意,您的逻辑分析仪还必须设置为相同的相位/极性时钟模式,以使其数据显示正确。

关于c - SPI 电子墨水显示器与 PIC 18F46K22 接口(interface)的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65503631/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com