0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PICとRPI4Bのuartシリアル通信 3. pwm-LED

Last updated at Posted at 2025-01-11

前回まで、PICとRPI4Bのuart通信を実施し、PICのキャラクターlcdに受信文字を表示し、更に受信文字をPICのspi-sramへの書込み・読み出しを確認しました。今回は、PIC側で、ハードウェアーpwmを使ってLEDの明るさを変えてみます。このハードウェアーpwmは、一回設定するとpwmモジュールが別個に動作しますので大変便利です。明るさを変えたい時にだけ、設定値を変更するだけです。

3.png

配線図です。PIC18F2620はCCP1とCCP2の2個を使っています。26k22はCCP4とCCP5の2個を使っています。すべてpwmとして使っています。どちらもStandard CCPと呼ばれている標準CCPのpwmを使っています。PIC18F26k22には、MCCPと呼ばれるハーフブリッジとフルブリッジPWM機能がありますが、今回は使っていません。
標準CCPしか使っていませんが、今回は、次の点がポイントです。PIC18F2620のCCP2は、Configuration BitsでRB3へピンを変更しています(CCP1、CCP2共に共通のTIMER2を使っています)。PIC18F26k22のCCP4とCCP5は、それぞれTIMER2とTIMER4を使っています。他は、PICの標準CCPのpwm設定です。

RPI4B側のPythonプログラムは、初回と同じものを使います。

# RPI-0-uart-tx.py
# Serial Console OFF, Serial ON
# RPI4B Buster(x32) Python 3.7.3 (x32) Thonny, and RUN  or 
# RPI4B bookworm(x64) Python 3.11.2 Thonny, and RUN
    
import serial
    
#Open SERIALttyS0
SERIALttyS0 = serial.Serial('/dev/ttyS0', 2304000, timeout=1)
    
#Set SendMessage
SendMessage = "Hello PIC Im Pi.Hello PIC Im Pi."
    
#Send Command
SERIALttyS0.write(SendMessage.encode())
    
#Receive ReturnMessage and print
binary_ReturnMessage = SERIALttyS0.readline()
ReturnMessage = binary_ReturnMessage.decode()
print(ReturnMessage)
    
#Close SERIALttyS0
SERIALttyS0.close()

PIC側のプログラムは、PICのハードウェアーpwmが増えています。今回も、xc8とC18のプログラムです。
PIC側のXC8プログラムです。

//main.c    MPLAB  X IDE v6.00,  XC8 Compiler v2.4.0, (C90),  PICkit3
//pic18f2620 or 26k22
#include <xc.h>
#define _XTAL_FREQ 36864000
#define LED_A0		LATA0
#define lcd_B7		LATB7
#define lcd_B6		LATB6
#define lcd_B5		LATB5
#define lcd_B4		LATB4
#define lcd_stb_E	LATA1
#define lcd_rs		LATA2
#define SPIRAM1024_CS_TRIS		TRISC1
#define SPIRAM1024_CS_IO		LATC1
#define SPIRAM1024_SCK_TRIS		TRISC3
#define SPIRAM1024_SDI_TRIS		TRISC4
#define SPIRAM1024_SDO_TRIS		TRISC5
#define SPIRAM1024_SPI_IF 		SSPIF
#define SPIRAM1024_SSPBUF		SSPBUF
#define SPIRAM1024_SPICON1		SSPCON1
#define SPIRAM1024_SPICON1bits	SSPCON1bits
#define SPIRAM1024_SPICON2		SSPCON2
#define SPIRAM1024_SPISTAT		SSPSTAT
#define SPIRAM1024_SPISTATbits	SSPSTATbits 
#define FXMA_CS0_TRIS	TRISC0
#define FXMA_CS0_IO		LATC0

//2620
#pragma config OSC = HSPLL
#pragma config FCMEN = OFF
#pragma config IESO = OFF
#pragma config PWRT = ON
#pragma config BOREN = OFF
#pragma config BORV = 3
#pragma config WDT = OFF
#pragma config WDTPS = 32768
#pragma config CCP2MX = PORTBE
#pragma config PBADEN = OFF
#pragma config LPT1OSC = OFF
#pragma config MCLRE = ON
#pragma config STVREN = OFF
#pragma config LVP = OFF
#pragma config XINST = OFF
#pragma config CP0 = OFF
#pragma config CP1 = OFF
#pragma config CP2 = OFF
#pragma config CP3 = OFF
#pragma config CPB = OFF
#pragma config CPD = OFF
#pragma config WRT0 = OFF
#pragma config WRT1 = OFF
#pragma config WRT2 = OFF
#pragma config WRT3 = OFF
#pragma config WRTC = OFF
#pragma config WRTB = OFF
#pragma config WRTD = OFF
#pragma config EBTR0 = OFF
#pragma config EBTR1 = OFF
#pragma config EBTR2 = OFF
#pragma config EBTR3 = OFF
#pragma config EBTRB = OFF

////26k22
//#pragma config FOSC = HSHP
//#pragma config PLLCFG = ON
//#pragma config PRICLKEN = ON
//#pragma config FCMEN = OFF
//#pragma config IESO = OFF
//#pragma config PWRTEN = ON
//#pragma config BOREN = OFF
//#pragma config BORV = 190
//#pragma config WDTEN = OFF
//#pragma config WDTPS = 32768
//#pragma config CCP2MX = PORTC1
//#pragma config PBADEN = OFF
//#pragma config CCP3MX = PORTB5
//#pragma config HFOFST = OFF
//#pragma config T3CMX = PORTC0
//#pragma config P2BMX = PORTB5
//#pragma config MCLRE = EXTMCLR
//#pragma config STVREN = OFF
//#pragma config LVP = OFF
//#pragma config XINST = OFF
//#pragma config CP0 = OFF
//#pragma config CP1 = OFF
//#pragma config CP2 = OFF
//#pragma config CP3 = OFF
//#pragma config CPB = OFF
//#pragma config CPD = OFF
//#pragma config WRT0 = OFF
//#pragma config WRT1 = OFF
//#pragma config WRT2 = OFF
//#pragma config WRT3 = OFF
//#pragma config WRTC = OFF
//#pragma config WRTB = OFF
//#pragma config WRTD = OFF
//#pragma config EBTR0 = OFF
//#pragma config EBTR1 = OFF
//#pragma config EBTR2 = OFF
//#pragma config EBTR3 = OFF
//#pragma config EBTRB = OFF

static unsigned char vBANK01[256];
static unsigned char vBuffer[32];

near uint8_t i,j,k,p,q,r,s;
near unsigned char asci, cmd, data, data0, Temp1, Temp2;
near uint16_t Wi, Wi_last, num, Wj, Wk, Wp, Wq, Wr, Ws;
near uint32_t Di, Dj, Dk;

near uint32_t dAddress, dAddreNewHead, dLength, dTotalLengh;
near uint8_t Dummy, SPICON1Save;

////   lcd functions
void LCD__vBuffer32(void);
void LCD__Data(unsigned char data);
void LCD__Command(unsigned char cmd);
void LCD__Command_Upper(unsigned char cmd);
void LCD__Init(void);
void LCD__Clear(void);
void PUT_DATA(void);
void PUT_CMD(void);

////   SPIRAM1024 functions
void SPIRAM1024Init(void);
void SPIRAM1024GetArray(near uint32_t dAddress, near uint32_t dLength);
void SPIRAM1024PutArray(near uint32_t dAddress, near uint32_t dLength);


void main()
{
    //2620
    ADCON0 = 0x00;
    ADCON1 = 0x0F;

    ////26k22
    //ANSELA = 0b00100000 ;    // AN4(RA5)
    //ANSELB = 0b00000000 ;
    //ANSELC = 0b00000000 ;

    TRISA  = 0b00100000 ;    // RA5
    TRISB  = 0b00000000 ;
    TRISC  = 0b00000000 ;
    PORTA  = 0b00000000 ;
    PORTB  = 0b00000000 ;
    PORTC  = 0b00000000 ;

    TRISC = 0x90;
    TXSTA = 0x24;
    RCSTA = 0x90;
    BAUDCON = 0x00;	
    SPBRG = 0x00;

    // sram init
    #if defined(SPIRAM1024_CS_TRIS)                
        SPIRAM1024Init();                            
    #endif    

    // lcd init
    LCD__Init();
    LCD__Command(0x01);
    LCD__Command(0x0c);

    Temp1=0x30;    
    for(i = 0; i < 32; i++)        
    {
        vBANK01[i]=Temp1;
        Temp1++;
    }

    for(i = 0; i < 32; i++)
    {
        vBuffer[i]=vBANK01[i];    
    }
    LCD__vBuffer32();
    __delay_ms(250);
    __delay_ms(250);
    __delay_ms(250);
    __delay_ms(250);

    SPIRAM1024PutArray(0,  32);

    for(i = 0; i < 32; i++)        
    {
        vBuffer[i]=0x30;
        vBANK01[i]=0x30;
    }
    LCD__vBuffer32();
    __delay_ms(1000);

    SPIRAM1024GetArray(0, 32);
    for(i = 0; i < 32; i++)        
    {
        vBuffer[i]=vBANK01[i];    
    }
    LCD__vBuffer32();
    __delay_ms(250);
    __delay_ms(250);
    __delay_ms(250);
    __delay_ms(250);

    FXMA_CS0_TRIS =0;
    FXMA_CS0_IO=0;

    Wi=0;
    Wi_last=31;
    for(; ; )
    {
        if (RCSTAbits.OERR)
        {
            RCSTAbits.CREN = 0;
            Temp1 = RCREG;
            RCSTAbits.CREN = 1;
        }
        if(RCIF==1) 
        {
            vBANK01[Wi]  = RCREG;
            Wi++;
        }
        if(Wi>Wi_last) {  break;  }
    }

    vBuffer[0] =0x48;  // H
    vBuffer[1] =0x45;  // E
    vBuffer[2] =0x4C;  // L
    vBuffer[3] =0x4C;  // L
    vBuffer[4] =0x4F;  // O
    vBuffer[5] =0x20;  // 
    vBuffer[6] =0x50;  // P
    vBuffer[7] =0x69;  // i
    vBuffer[8] =0x20;  // 
    vBuffer[9] =0x49;  // I
    vBuffer[10]=0x6D;  // m
    vBuffer[11]=0x20;  // 
    vBuffer[12]=0x50;  // P
    vBuffer[13]=0x49;  // I
    vBuffer[14]=0x43;  // C
    vBuffer[15]=0x40;  // @
    vBuffer[16]=0x0A;  // LF

    Wi=0;
    Wi_last=17;
    for(; ; )
    {
        //2620
        if(TRMT==1)
        26k22
        //if(TXSTAbits.TRMT==1)
        {
            TXREG  =  vBuffer[Wi];
            Wi++;
        }
        if(Wi>Wi_last) {  break;  }
    }

    FXMA_CS0_IO=1;

    SPIRAM1024PutArray(0, 256);

    for(i = 0; i < 32; i++)        
    {
    	vBuffer[i]=0x30;
    	vBANK01[i]=0x30;
    }
    
    dAddreNewHead = 0;
    SPIRAM1024GetArray(dAddreNewHead, 32);
 
    for(i = 0; i < 32; i++)        
    {
    	vBuffer[i]=vBANK01[i];    
    }
    LCD__vBuffer32();
    __delay_ms(250);
    __delay_ms(250);
    __delay_ms(250);
    __delay_ms(250);
    __delay_ms(250);
    __delay_ms(250);
    __delay_ms(250);
    __delay_ms(250);
    
    ////// 2620 pwm,  STANDARD CCP1(RC2 default) and STANDARD CCP2(changed from RC1 to RB3 by Configuration Bits) init
    ////// E-p140, Table 15-2, Both PWMs will have the same frequency and update rate (TMR2 interrupt).
    ////// Timer is only (TMR2, PR2, and T2CON) set.
    CCP1CON  = 0b00001100 ;  // (2620 E-p146)  PWM mode,     *(2) unimplemented on 28-pin
    //		*2	*2			DC2B1 		DC2B0		CCP2M3		CCP2M2		CCP2M1		CCP2M0
    //		0	0			0			0			1			1			0			0
    CCP2CON  = 0b00001100 ;  // (2620 E-p139)  PWM mode
    //		— 	— 			DC2B1 		DC2B0		CCP2M3		CCP2M2		CCP2M1		CCP2M0
    //		0	0			0			0			1			1			0			0
    T2CON	= 0b00000010 ;  // (2620 E-p133)   Timer2 is off,   Prescaler is 16
    //		— 	T2OUTPS3	T2OUTPS2	T2OUTPS1	T2OUTPS0	TMR2ON		T2CKPS1		T2CKPS0
    //		0	0			0			0			0			0			1			0
    CCPR1L   = 0 ;
    CCPR1H   = 0 ;
    CCPR2L   = 0 ;
    CCPR2H   = 0 ;
    TMR2     = 0 ;
    PR2      = 249 ;
    T2CONbits.TMR2ON   = 1 ;

    ////// 26K22 pwm,  STANDARD CCP4(RB0) and CCP5(RA4) init
    //CCPTMRS1 = 0b00000100 ;  // (26k22 G-p201)	CCP5 PWM modes use Timer4	CCP4 PWM modes use Timer2
    //		— 		— 		— 			— 			C5TSEL1		C5TSEL0		C4TSEL1		C4TSEL0
    //		0		0		0			0			0			1			0			0
    //CCP4CON  = 0b00001100 ;  // (26k22 G-p198)  STANDARD  CCP4    PWM mode
    //		—		—		DC4B1		DC4B0		CCP4M3		CCP4M1		CCP4M1		CCP4M0	
    //		0		0		0			0			1			1			0			0
    //CCP5CON  = 0b00001100 ;  // (26k22 G-p198)  STANDARD  CCP5    PWM mode
    //		—		—		DC5B1		DC5B0		CCP5M3		CCP5M1		CCP5M1		CCP5M0	
    //		0		0		0			0			1			1			0			0
    //T2CON	= 0b00000010 ;  // (26k22 G-p165)   Timer2 is off,   Prescaler is 16
    //		TMR2CS1	TMR2CS0	T2CKPS1		T2CKPS0		T2SOSCEN 	T2SYNC 		T2RD16		TMR2ON
    //		0		0		0			0			0			0			1			0
    //T4CON	= 0b00000010 ;  // (26k22 G-p165)   Timer4 is off,   Prescaler is 16
    //		TMR4CS1	TMR4CS0	T4CKPS1		T4CKPS0		T4SOSCEN 	T4SYNC 		T4RD16		TMR4ON
    //		0		0		0			0			0			0			1			0
    //CCPR4L   = 0 ;
    //CCPR4H   = 0 ;
    //CCPR5L   = 0 ;
    //CCPR5H   = 0 ;
    //TMR2     = 0 ;
    //TMR4     = 0 ;
    //PR2      = 249 ;         // G-p182
    //PR4      = 249 ;         // G-p182
    //T2CONbits.TMR2ON   = 1 ;
    //T4CONbits.TMR4ON   = 1 ;

    while(1) {

        LED_A0 = 1;
        //2620
        for(Wi=0; Wi<=1023; Wi++)
        {
            CCPR1L = Wi/4 ;
            CCPR2L = (1023-Wi)/4 ;
            __delay_ms(2) ;
        }
        ////26k22
        //for(Wi=0; Wi<=1023; Wi++)
        //{
        //    CCPR4L = Wi/4 ;
        //    CCPR5L = (1023-Wi)/4 ;
        //    __delay_ms(2) ;
        //}

        LED_A0 = 0;
        //2620
        for(Wi=0; Wi<=1023; Wi++)
        {
            CCPR1L = (1023-Wi)/4 ;
            CCPR2L = Wi/4 ;
            __delay_ms(2) ;
        }
        ////26k22
        //for(Wi=0; Wi<=1023; Wi++)
        //{
        //    CCPR4L = (1023-Wi)/4 ;
        //    CCPR5L = Wi/4 ;
        //    __delay_ms(2) ;
        //}
     }
}


//  SC1602BS lcd functios  //

void LCD__vBuffer32(void)
{
	uint8_t ii;
	LCD__Clear();
	for(ii = 0; ii < 16; ii++){
		data= vBuffer[ii];
		LCD__Data(data);
	}
	LCD__Command(0xC0);
	for(ii = 16; ii < 32; ii++){
		data= vBuffer[ii];
		LCD__Data(data);
	}
}

void LCD__Data(unsigned char data)
{
	uint8_t jj;
	for(jj=0; jj<=1; jj++)
	{
		if (jj==0)
			data0=data;
		else
			data0=data<<4;
		lcd_B7 = 0;
		lcd_B6 = 0;
		lcd_B5 = 0;
		lcd_B4 = 0;
		if((data0 & 0x80) != 0)
			lcd_B7 = 1;
		if((data0 & 0x40) != 0)
			lcd_B6 = 1;
		if((data0 & 0x20) != 0)
			lcd_B5 = 1;
		if((data0 & 0x10) != 0)
			lcd_B4 = 1;
		PUT_DATA();
	}
	__delay_us(50);
}

void LCD__Command(unsigned char cmd)
{
	uint8_t jj;
	for(jj=0; jj<=1; jj++)
	{
		if (jj==0)
			data0=cmd;
		else
			data0=cmd<<4;
		lcd_B7 = 0;
		lcd_B6 = 0;
		lcd_B5 = 0;
		lcd_B4 = 0;
		if((data0 & 0x80) != 0)
			lcd_B7 = 1;
		if((data0 & 0x40) != 0)
			lcd_B6 = 1;
		if((data0 & 0x20) != 0)
			lcd_B5 = 1;
		if((data0 & 0x10) != 0)
			lcd_B4 = 1;
		PUT_CMD();
	}
	__delay_us(50);
}

void LCD__Command_Upper(unsigned char cmd)
{
	lcd_B7 = 0;
	lcd_B6 = 0;
	lcd_B5 = 0;
	lcd_B4 = 0;
	if((data0 & 0x80) != 0)
		lcd_B7 = 1;
	if((data0 & 0x40) != 0)
		lcd_B6 = 1;
	if((data0 & 0x20) != 0)
		lcd_B5 = 1;
	if((data0 & 0x10) != 0)
		lcd_B4 = 1;
	PUT_CMD();
	__delay_ms(5);
}

void LCD__Clear(void)
{
	LCD__Command(0x01);
	__delay_ms(250);
}

void LCD__Init(void)
{
	__delay_ms(50);
	LCD__Command_Upper(0x30);
	LCD__Command_Upper(0x30);
	LCD__Command_Upper(0x30);
	LCD__Command_Upper(0x20);
	LCD__Command(0x2E);
	LCD__Command(0x08);
	LCD__Command(0x0D);
	LCD__Command(0x06);
	LCD__Clear();
}

void PUT_CMD(void)
{
	lcd_rs  = 0;
	_delay(1);
	lcd_stb_E = 1;
	_delay(4);
	lcd_stb_E = 0;
}

void PUT_DATA(void)
{
	lcd_rs  = 1;
	_delay(1);
	lcd_stb_E = 1;
	_delay(4);
	lcd_stb_E = 0;
}


//// no-pointer spi-sram 23LC1024 functions,  referred from Microchip
// opcodes
#define READ	0x03			// Read data from memory array beginning at selected address
#define WRITE	0x02			// Write data to memory array beginning at selected address
#define RDSR	0x05			// Read Status register
#define WRSR	0x01			// Write Status register
// define
#define PROPER_SPICON1	(0x20)		// SSPEN bit is set, SPI in master mode, FOSC/4, IDLE state is low level

void SPIRAM1024Init(void)
{
	SPIRAM1024_CS_IO = 1;
	SPIRAM1024_CS_TRIS = 0;
	SPIRAM1024_SCK_TRIS = 0;
	SPIRAM1024_SDI_TRIS = 1;	
	SPIRAM1024_SDO_TRIS = 0;
	// Save SPI state (clock speed)
	SPICON1Save = SPIRAM1024_SPICON1;
	SPIRAM1024_SPICON1 = PROPER_SPICON1;
	SPIRAM1024_SPI_IF = 0;
	SPIRAM1024_SPISTATbits.CKE = 1; 
	SPIRAM1024_SPISTATbits.SMP = 0;
	// Set Burst mode
	// Activate chip select
	SPIRAM1024_CS_IO = 0;
	SPIRAM1024_SPI_IF = 0;
	// Send Write Status Register opcode
	SPIRAM1024_SSPBUF = WRSR;
	while(!SPIRAM1024_SPI_IF);
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	// Set status register to 0b01000000 to enable burst mode
	SPIRAM1024_SSPBUF = 0x40;
	while(!SPIRAM1024_SPI_IF);
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	// Deactivate chip select
	SPIRAM1024_CS_IO = 1;
	// Restore SPI state
	SPIRAM1024_SPICON1 = SPICON1Save;
}

void SPIRAM1024GetArray(near uint32_t dAddress, near uint32_t dLength)
{
	if(dLength == 0)
		return;
	// Save SPI state (clock speed)
	SPICON1Save = SPIRAM1024_SPICON1;
	SPIRAM1024_SPICON1 = PROPER_SPICON1;
	// Activate chip select
	SPIRAM1024_CS_IO = 0;
	SPIRAM1024_SPI_IF = 0;
	// Send READ opcode
	SPIRAM1024_SSPBUF = READ;
	while(!SPIRAM1024_SPI_IF);
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	// Send address
	SPIRAM1024_SSPBUF = ((uint8_t*)&dAddress)[2];
	while(!SPIRAM1024_SPI_IF);	
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	//
	SPIRAM1024_SSPBUF = ((uint8_t*)&dAddress)[1];
	while(!SPIRAM1024_SPI_IF);
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	//
	SPIRAM1024_SSPBUF = ((uint8_t*)&dAddress)[0];
	while(!SPIRAM1024_SPI_IF);
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	// Read data
	for(Dk = 0; Dk < dLength; Dk++)
	{
		SPIRAM1024_SSPBUF = 0;
		while(!SPIRAM1024_SPI_IF);
		vBANK01[Dk] = SPIRAM1024_SSPBUF;
		SPIRAM1024_SPI_IF = 0;
	}
	// Deactivate chip select
	SPIRAM1024_CS_IO = 1;
	// Restore SPI state
	SPIRAM1024_SPICON1 = SPICON1Save;
}

void SPIRAM1024PutArray(near uint32_t dAddress, near uint32_t dLength)
{
	if(dLength == 0)
		return;
	// Save SPI state (clock speed)
	SPICON1Save = SPIRAM1024_SPICON1;
	SPIRAM1024_SPICON1 = PROPER_SPICON1;
	// Activate chip select
	SPIRAM1024_CS_IO = 0;
	SPIRAM1024_SPI_IF = 0;
	// Send WRITE opcode
	SPIRAM1024_SSPBUF = WRITE;
	while(!SPIRAM1024_SPI_IF);
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	// Send address
	SPIRAM1024_SSPBUF = ((uint8_t*)&dAddress)[2];
	while(!SPIRAM1024_SPI_IF);	
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	//
	SPIRAM1024_SSPBUF = ((uint8_t*)&dAddress)[1];
	while(!SPIRAM1024_SPI_IF);
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	//
	SPIRAM1024_SSPBUF = ((uint8_t*)&dAddress)[0];
	while(!SPIRAM1024_SPI_IF);
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	// Write data
	for(Dk = 0; Dk < dLength; Dk++)
	{
		SPIRAM1024_SSPBUF = vBANK01[Dk];
		while(!SPIRAM1024_SPI_IF);
		Dummy = SPIRAM1024_SSPBUF;
		SPIRAM1024_SPI_IF = 0;
	}
	// Deactivate chip select
	SPIRAM1024_CS_IO = 1;
	// Restore SPI state
	SPIRAM1024_SPICON1 = SPICON1Save;
}

PIC側のC18プログラムです。

// MainDemo.c     MPLAB_IDE_8_92,  MPLAB_C18_3.46,  PICkit3
#include <p18f2620.h>
//#include <p18f26k22.h>
#include <HardwareProfile.h>
#include <GenericTypeDefs.h>
#include <delays.h>
#pragma udata bank1  = 0x100
static unsigned char vBANK01[256];
#pragma udata bank2 = 0x200
static unsigned char vBuffer[32];
#pragma udata access my_access
near unsigned char asci, cmd, data, data0, Temp1, Temp2;
near BYTE i, j, k, ii, jj, kk;
near WORD Wi, Wi_last, num, Wj, Wk, Wp, Wq, Wr, Ws;
near DWORD Di, Dj, Dk;
near DWORD dAddress, dAddreNewHead, dLength, dTotalLengh;
near BYTE Dummy, SPICON1Save;
// LCD functions
void LCD__Data(void);
void LCD__vBuffer32(void);
void LCD__Command(void);
void LCD__Clear(void);
void LCD__Init(void);
void PUT_CMD(void);
void PUT_DATA(void);
// Time functions
void TIME50(void);
void TIME5M(void);
// SPI-SRAM1024 functions 
void SPIRAM1024Init(void);
void SPIRAM1024GetArray(near DWORD dAddress, near DWORD dLength);
void SPIRAM1024PutArray(near DWORD dAddress, near DWORD dLength);

#pragma code
void main(void){

	//2620
	ADCON0 = 0x00;
	ADCON1 = 0x0F;
	////26k22
	//ANSELA = 0b00100000 ;    // AN4(RA5)
	//ANSELB = 0b00000000 ;
	//ANSELC = 0b00000000 ;
	TRISA  = 0b00100000 ;    // RA5
	TRISB  = 0b00000000 ;
	TRISC  = 0b00000000 ;
	PORTA  = 0b00000000 ;
	PORTB  = 0b00000000 ;
	PORTC  = 0b00000000 ;
	TRISC = 0x90;
	TXSTA = 0x24;
	RCSTA = 0x90;
	BAUDCON = 0x00;	
	SPBRG = 0x00;

	LCD__Init();

	#if defined(SPIRAM1024_CS_TRIS)				
		SPIRAM1024Init();							
	#endif																		

	Temp1=0x41;	
	for(i = 0; i < 32; i++)		
	{
		vBANK01[i]=Temp1;	
		_asm  INCF  Temp1, 1, 0  _endasm
	}
	for(i = 0; i < 32; i++)
	{
		vBuffer[i]=vBANK01[i];	
	}
	LCD__vBuffer32();
	Delay10KTCYx(250);
	Delay10KTCYx(250);
	Delay10KTCYx(250);
	Delay10KTCYx(250);

	SPIRAM1024PutArray(0,  32);	    // SRAM Write

	for(i = 0; i < 32; i++)	    	   // clear buffer
	{
		vBuffer[i]=0x30;
		vBANK01[i]=0x30;
	}
	LCD__vBuffer32();
	Delay10KTCYx(250);
	Delay10KTCYx(250);
	Delay10KTCYx(250);
	Delay10KTCYx(250);

	SPIRAM1024GetArray(0, 32);	    // SRAM Read	
	for(i = 0; i < 32; i++)		
	{
		vBuffer[i]=vBANK01[i];	
	}
	LCD__vBuffer32();
	Delay10KTCYx(250);
	Delay10KTCYx(250);
	Delay10KTCYx(250);
	Delay10KTCYx(250);

	LED0_IO = 0;

	FXMA_CS0_TRIS = 0;
	FXMA_CS0_IO = 0;

	for(Wi = 0; Wi < 32; Wi++)
	{
		if (RCSTAbits.OERR) 
		{
			RCSTAbits.CREN = 0;
			Temp1 = RCREG;
			RCSTAbits.CREN = 1;
		}
		_asm BTFSS  PIR1, 5, 0 _endasm      // RCIF in P1R1 = 5
		_asm BRA -2	       _endasm
		vBANK01[Wi]  = RCREG;
	}

	vBuffer[0] =0x48;  // H
	vBuffer[1] =0x45;  // E
	vBuffer[2] =0x4C;  // L
	vBuffer[3] =0x4C;  // L
	vBuffer[4] =0x4F;  // O
	vBuffer[5] =0x20;  // 
	vBuffer[6] =0x50;  // P
	vBuffer[7] =0x69;  // i
	vBuffer[8] =0x20;  // 
	vBuffer[9] =0x49;  // I
	vBuffer[10]=0x6D;  // m
	vBuffer[11]=0x20;  // 
	vBuffer[12]=0x50;  // P
	vBuffer[13]=0x49;  // I
	vBuffer[14]=0x43;  // C
	vBuffer[15]=0x40;  // @
	vBuffer[16]=0x0A;  // LF

	for(i = 0; i < 18; i++)		
	{
		_asm BTFSS TXSTA, 1, 0 _endasm      // TRMT in TXSTA = 1
		_asm BRA   -2	       _endasm
		TXREG  =  vBuffer[i];
	}

	FXMA_CS0_IO = 1;

	SPIRAM1024PutArray(0, 256);       // SRAM Write

	for(i = 0; i < 32; i++)		
	{
		vBuffer[i]=0x30;
		vBANK01[i]=0x30;
	}
	
	dAddreNewHead = 0;
	SPIRAM1024GetArray(dAddreNewHead, 32);    // SRAM Read

	for(i = 0; i < 32; i++)		
	{
		vBuffer[i]=vBANK01[i];	
	}
	LCD__vBuffer32();
	Delay10KTCYx(250);
	Delay10KTCYx(250);
	Delay10KTCYx(250);
	Delay10KTCYx(250);
	Delay10KTCYx(250);
	Delay10KTCYx(250);
	Delay10KTCYx(250);
	Delay10KTCYx(250);

	////// 2620 pwm,  STANDARD CCP1(RC2 default) and STANDARD CCP2(changed from RC1 to RB3 by Configuration Bits) init
	////// E-p140, Table 15-2, Both PWMs will have the same frequency and update rate (TMR2 interrupt).
	////// Timer is only (TMR2, PR2, and T2CON) set.
	CCP1CON  = 0b00001100 ;  // (2620 E-p146)  PWM mode,     *(2) unimplemented on 28-pin
	//		*(2)	*(2)		DC2B1 		DC2B0		CCP2M3		CCP2M2		CCP2M1		CCP2M0
	//		0		0			0			0			1			1			0			0
	CCP2CON  = 0b00001100 ;  // (2620 E-p139)  PWM mode
	//		— 		— 			DC2B1 		DC2B0		CCP2M3		CCP2M2		CCP2M1		CCP2M0
	//		0		0			0			0			1			1			0			0
	T2CON	= 0b00000010 ;  // (2620 E-p133)   Timer2 is off,   Prescaler is 16
	//		— 		T2OUTPS3	T2OUTPS2	T2OUTPS1	T2OUTPS0	TMR2ON		T2CKPS1		T2CKPS0
	//		0		0			0			0			0			0			1			0
	CCPR1L   = 0 ;
	CCPR1H   = 0 ;
	CCPR2L   = 0 ;
	CCPR2H   = 0 ;
	TMR2	 = 0 ;
	PR2	  = 249 ;
	T2CONbits.TMR2ON   = 1 ;

	////// 26K22 pwm,  STANDARD CCP4(RB0) and CCP5(RA4) init
	//CCPTMRS1 = 0b00000100 ;  // (26k22 G-p201)	CCP5 PWM modes use Timer4	CCP4 PWM modes use Timer2
	//		— 		— 			— 			— 			C5TSEL1		C5TSEL0		C4TSEL1		C4TSEL0
	//		0		0			0			0			0			1			0			0
	//CCP4CON  = 0b00001100 ;  // (26k22 G-p198)  STANDARD  CCP4    PWM mode
	//		—		—			DC4B1		DC4B0		CCP4M3		CCP4M1		CCP4M1		CCP4M0	
	//		0		0			0			0			1			1			0			0
	//CCP5CON  = 0b00001100 ;  // (26k22 G-p198)  STANDARD  CCP5    PWM mode
	//		—		—			DC5B1		DC5B0		CCP5M3		CCP5M1		CCP5M1		CCP5M0	
	//		0		0			0			0			1			1			0			0
	//T2CON	= 0b00000010 ;  // (26k22 G-p165)   Timer2 is off,   Prescaler is 16
	//		TMR2CS1	TMR2CS0		T2CKPS1		T2CKPS0		T2SOSCEN 	T2SYNC 		T2RD16		TMR2ON
	//		0		0			0			0			0			0			1			0
	//T4CON	= 0b00000010 ;  // (26k22 G-p165)   Timer4 is off,   Prescaler is 16
	//		TMR4CS1	TMR4CS0		T4CKPS1		T4CKPS0		T4SOSCEN 	T4SYNC 		T4RD16		TMR4ON
	//		0		0			0			0			0			0			1			0
	//CCPR4L   = 0 ;
	//CCPR4H   = 0 ;
	//CCPR5L   = 0 ;
	//CCPR5H   = 0 ;
	//TMR2	 = 0 ;
	//TMR4	 = 0 ;
	//PR2	  = 249 ;		 // G-p182
	//PR4	  = 249 ;		 // G-p182
	//T2CONbits.TMR2ON   = 1 ;
	//T4CONbits.TMR4ON   = 1 ;

	while(1)
	{
		LED0_IO = 1;
		//2620
		for(Wi=0; Wi<=1023; Wi++)
		{
			CCPR1L = Wi/4 ;
			CCPR2L = (1023-Wi)/4 ;
			Delay10KTCYx(2);
		}
		////26k22
		//for(Wi=0; Wi<=1023; Wi++)
		//{
		//	CCPR4L = Wi/4 ;
		//	CCPR5L = (1023-Wi)/4 ;
		//	Delay10KTCYx(2);
		//}

		LED0_IO = 0;
		//2620
		for(Wi=0; Wi<=1023; Wi++)
		{
			CCPR1L = (1023-Wi)/4 ;
			CCPR2L = Wi/4 ;
			Delay10KTCYx(2);
		}
		////26k22
		//for(Wi=0; Wi<=1023; Wi++)
		//{
		//	CCPR4L = (1023-Wi)/4 ;
		//	CCPR5L = Wi/4 ;
		//	Delay10KTCYx(2);
		//}
	}	
}


#pragma tmpdata
//// lcd functions
void LCD__Data(void)
{
	_asm MOVWF Temp1, 0 	_endasm
    _asm MOVLW 0x0F 		_endasm
	_asm ANDWF PORTB, 1, 0 	_endasm
	_asm MOVF  Temp1, 0, 0 	_endasm
	_asm ANDLW 0xF0 		_endasm
	_asm IORWF PORTB, 1, 0 	_endasm
	PUT_DATA();
	_asm MOVLW 0x0F 		_endasm
	_asm ANDWF PORTB, 1, 0 	_endasm
	_asm SWAPF Temp1, 0, 0  _endasm
	_asm ANDLW 0xF0 		_endasm
	_asm IORWF PORTB, 1, 0 	_endasm
	PUT_DATA();
	TIME50();
}

void LCD__vBuffer32(void)
{
	LCD__Clear();
	for(kk = 0; kk < 16; kk++)		
	{
		Temp1= vBuffer[kk];
		LCD__Data();
	}
	_asm MOVLW 0xC0  		_endasm	
	LCD__Command();			
	TIME50();
	for(kk = 16; kk < 32; kk++)		
	{
		Temp1= vBuffer[kk];
		LCD__Data();
	}
}

void PUT_CMD(void)
{	
	lcd_rs  = 0;
	Nop();
	lcd_stb = 1;
	Nop();				
	Nop();
	Nop();				
	Nop();	
	lcd_stb = 0;
}

void PUT_DATA(void)
{
	lcd_rs  = 1;
	Nop();
	lcd_stb = 1;
	Nop();				
	Nop();
	Nop();				
	Nop();	
	lcd_stb = 0;
}

void LCD__Command(void)
{
	_asm MOVWF Temp1, 0 	_endasm		
	_asm MOVLW 0x0F 		_endasm		
	_asm ANDWF PORTB, 1, 0 	_endasm		
	_asm MOVF  Temp1, 0, 0 	_endasm		
	_asm ANDLW 0xF0 		_endasm		
	_asm IORWF PORTB, 1, 0 	_endasm		
	PUT_CMD();
	_asm MOVLW 0x0F 		_endasm
	_asm ANDWF PORTB, 1, 0 	_endasm		
	_asm SWAPF Temp1, 0, 0  _endasm		
	_asm ANDLW 0xF0 		_endasm
	_asm IORWF PORTB, 1, 0 	_endasm		
	PUT_CMD();
	TIME50();				
}

void LCD__Clear(void)
{
	_asm MOVLW 0x01  		_endasm
	LCD__Command();	
	Delay10KTCYx(125);
	Delay10KTCYx(125);
}

void LCD__Init(void)
{	
	TIME5M();
	TIME5M();
	TIME5M();
	TIME5M();
	TIME5M();
	TIME5M();
	TIME5M();
	_asm MOVLW	0x0F	 		_endasm
	_asm ANDWF	PORTB,    1, 0 	_endasm
	_asm MOVLW	0x30			_endasm
	_asm IORWF	PORTB,    1, 0 	_endasm
	PUT_CMD();
	TIME5M();
	PUT_CMD();
	TIME5M();
	PUT_CMD();
	TIME5M();
	_asm MOVLW	0x0F	 		_endasm
	_asm ANDWF	PORTB,    1, 0 	_endasm	
	_asm MOVLW	0x20	 		_endasm
	_asm IORWF	PORTB,    1, 0 	_endasm
	PUT_CMD();
	TIME5M();
	_asm MOVLW 0x2E  			_endasm	
	LCD__Command();	
	_asm MOVLW 0x08 			_endasm
	LCD__Command();	
	_asm MOVLW 0x0D  			_endasm
	LCD__Command();	
	_asm MOVLW 0x06  			_endasm
	LCD__Command();	
	LCD__Clear();
}

//  about 50usec at 40MHz
void TIME50(void)
{
	_asm MOVLW	0x63		_endasm
	_asm MOVWF	ii, 0		_endasm 
	_asm NOP				_endasm
	_asm NOP				_endasm
	_asm DECFSZ	ii, 1, 0	_endasm	
	_asm BRA	-4			_endasm
}

//  about 5msec at 40MHz
void TIME5M(void)
{
	_asm MOVLW	0x64		_endasm
	_asm MOVWF	jj, 0		_endasm
	TIME50();
	_asm DECFSZ	jj, 1, 0	_endasm
	_asm BRA	-3			_endasm
}

//// no-pointer spi-sram (23LC1024) functions : referred from Microchip
// opcodes
#define READ	0x03			// Read data from memory array beginning at selected address
#define WRITE	0x02			// Write data to memory array beginning at selected address
#define RDSR	0x05			// Read Status register
#define WRSR	0x01			// Write Status register
// define
#define PROPER_SPICON1	(0x20)		// SSPEN bit is set, SPI in master mode, FOSC/4, IDLE state is low level

void SPIRAM1024Init(void)
{
	SPIRAM1024_CS_IO = 1;
	SPIRAM1024_CS_TRIS = 0;
	SPIRAM1024_SCK_TRIS = 0;		// SCK pin    output
	SPIRAM1024_SDI_TRIS = 1;		// SDI pin     input
	SPIRAM1024_SDO_TRIS = 0;		// SDO pin    output
	// Save SPI state (clock speed)
	SPICON1Save = SPIRAM1024_SPICON1;
	SPIRAM1024_SPICON1 = PROPER_SPICON1;
	SPIRAM1024_SPI_IF = 0;
	SPIRAM1024_SPISTATbits.CKE = 1; 	// Transmit data on rising edge of clock
	SPIRAM1024_SPISTATbits.SMP = 0;		// Input sampled at middle of data output time
	// Set Burst mode
	// Activate chip select
	SPIRAM1024_CS_IO = 0;
	SPIRAM1024_SPI_IF = 0;
	// Send Write Status Register opcode
	SPIRAM1024_SSPBUF = WRSR;
	while(!SPIRAM1024_SPI_IF);
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	// Set status register to 0b01000000 to enable burst mode
	SPIRAM1024_SSPBUF = 0x40;
	while(!SPIRAM1024_SPI_IF);
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	// Deactivate chip select
	SPIRAM1024_CS_IO = 1;
	// Restore SPI state
	SPIRAM1024_SPICON1 = SPICON1Save;
}

void SPIRAM1024GetArray(near DWORD dAddress, near DWORD dLength)
{
	// Ignore operations when the destination is NULL or nothing to read
	if(vBANK01 == NULL)
		return;
	if(dLength == 0)
		return;
	// Save SPI state (clock speed)
	SPICON1Save = SPIRAM1024_SPICON1;
	SPIRAM1024_SPICON1 = PROPER_SPICON1;
	// Activate chip select
	SPIRAM1024_CS_IO = 0;
	SPIRAM1024_SPI_IF = 0;
	// Send READ opcode
	SPIRAM1024_SSPBUF = READ;
	while(!SPIRAM1024_SPI_IF);
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	// Send address
	SPIRAM1024_SSPBUF = ((BYTE*)&dAddress)[2];
	while(!SPIRAM1024_SPI_IF);	
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	//
	SPIRAM1024_SSPBUF = ((BYTE*)&dAddress)[1];
	while(!SPIRAM1024_SPI_IF);
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	//
	SPIRAM1024_SSPBUF = ((BYTE*)&dAddress)[0];
	while(!SPIRAM1024_SPI_IF);
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	// Read data
	for(Dk = 0; Dk < dLength; Dk++)
	{
		SPIRAM1024_SSPBUF = 0;
		while(!SPIRAM1024_SPI_IF);
		vBANK01[Dk] = SPIRAM1024_SSPBUF;
		SPIRAM1024_SPI_IF = 0;
	}
	// Deactivate chip select
	SPIRAM1024_CS_IO = 1;
	// Restore SPI state
	SPIRAM1024_SPICON1 = SPICON1Save;
}

void SPIRAM1024PutArray(near DWORD dAddress, near DWORD dLength)
{
	// Ignore operations when the source data is NULL
	if(vBANK01 == NULL)
		return;
	if(dLength == 0)
		return;
	// Save SPI state (clock speed)
	SPICON1Save = SPIRAM1024_SPICON1;
	SPIRAM1024_SPICON1 = PROPER_SPICON1;
	// Activate chip select
	SPIRAM1024_CS_IO = 0;
	SPIRAM1024_SPI_IF = 0;
	// Send WRITE opcode
	SPIRAM1024_SSPBUF = WRITE;
	while(!SPIRAM1024_SPI_IF);
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	// Send address
	SPIRAM1024_SSPBUF = ((BYTE*)&dAddress)[2];
	while(!SPIRAM1024_SPI_IF);	
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	////
	SPIRAM1024_SSPBUF = ((BYTE*)&dAddress)[1];
	while(!SPIRAM1024_SPI_IF);
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	////
	SPIRAM1024_SSPBUF = ((BYTE*)&dAddress)[0];
	while(!SPIRAM1024_SPI_IF);
	Dummy = SPIRAM1024_SSPBUF;
	SPIRAM1024_SPI_IF = 0;
	// Write data
	for(Dk = 0; Dk < dLength; Dk++)
	{
		SPIRAM1024_SSPBUF = vBANK01[Dk];
		while(!SPIRAM1024_SPI_IF);
		Dummy = SPIRAM1024_SSPBUF;
		SPIRAM1024_SPI_IF = 0;
	}
	// Deactivate chip select
	SPIRAM1024_CS_IO = 1;
	// Restore SPI state
	SPIRAM1024_SPICON1 = SPICON1Save;
}

C18用のHardwareProfile.hとConfiguration Bitsは、前回
と同じです。

次回はPIC側で、drv8835モータードライバーを使って、DCモーターを、加速・減速・停止、正転・逆転します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?