初回、PICとRPI4Bの2.3Mbpsでの高速uart通信を実施しました。そしてPIC側では、キャラクターlcdとspi-sramを追加し、さらに前回は、DC-motorドライバーのTI社製DRV8835を使い、モーターを動かしました。今回は、ADコンバーターを追加してみます。
配線図です。MCP9700温度センサーを追加しただけです。MCP9700は、両端のピンをそれぞれ5Vと0Vに接続するだけで、温度に比例する電圧が真中のピンからアナログ出力されます。抵抗、コンデンサーも、必要ありません。プログラム上でADコンバーターを試行する時に便利です。室温~100℃前後まで、比較的高い直線性があります。室温付近では、0.5℃程度の誤差範囲です。プログラム中で温度較正表または較正式を適用すれば、相当な実用的精度がありますが、今回は較正していません。
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側のプログラムは、A/Dコンバーターを追加しています。アナログ入力に設定しているRA5ピンの0~5Vの電圧を、PIC内蔵の10bitのA/Dコンバーターモジュールで、0~1023の数値に変換します。今回も、xc8とC18のプログラムです。
PIC18Fの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);
//// ADC function
uint16_t adconv(void);
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 and CCP2 init
CCP1CON = 0b00001100 ;
CCP2CON = 0b00001100 ;
T2CON = 0b00000010 ;
CCPR1L = 0 ;
CCPR1H = 0 ;
CCPR2L = 0 ;
CCPR2H = 0 ;
TMR2 = 0 ;
PR2 = 249 ;
T2CONbits.TMR2ON = 1 ;
////// 26K22 pwm, Standard CCP4 and CCP5 init
//CCPTMRS1 = 0b00000100 ;
//CCP4CON = 0b00001100 ;
//CCP5CON = 0b00001100 ;
//T2CON = 0b00000010 ;
//T4CON = 0b00000010 ;
//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 ;
// ADC init
ADCON0 = 0b00010001 ;
ADCON1 = 0b00000000 ;
ADCON2 = 0b10010101 ;
__delay_us(8) ;
//// details
//// 2620 ADC init details, (2620 E-pp223-225)
//ADCON0 = 0b00010001 ; // select AN4(RA5). A/D Converter module is enabled
// ADCON0 — — CHS3 CHS2 CHS1 CHS0 GO/DONE ADON
// 0 0 0 1 0 0 0 1
//ADCON1 = 0b00000000 ; // Vss and Vdd. PCFG<2:0> = 111 by PBADEN = 0 in Confuguration Bits. only AN4(RA5) A/D input by TRISA = 0b00100000, not affected by analog input of ADCON1 (2620-E-p92).
// ADCON1 — — VCFG1 VCFG0 PCFG3 PCFG2 PCFG1 PCFG0
// 0 0 0 0 0 0 0 0
//ADCON2 = 0b10010101 ; // Right justified, Acquisition Time 4Tad, Conversion Clock FOSC/16
// ADCON2 ADFM — ACQT2 ACQT1 ACQT0 ADCS2 ADCS1 ADCS0
// 1 0 0 1 0 1 0 1
//// 26k22 ADC init details, (26k22 G-pp149-152, pp295-298)
//ADCON0 = 0b00010001 ; // select AN4(RA5). A/D Converter module is enabled
// ADCON0 — CHS4 CHS3 CHS2 CHS1 CHS0 GO/DONE ADON
// 0 0 0 1 0 0 0 1
//ADCON1 = 0b00000000 ;
// ADCON1 TRIGSEL — — — PVCFG1 PVCFG0 NVCFG1 NVCFG0
// 0 0 0 0 0 0 0 0
//ADCON2 = 0b10010101 ;
// ADCON2 ADFM — ACQT2 ACQT1 ACQT0 ADCS2 ADCS1 ADCS0
// 1 0 0 1 0 1 0 1
while(1) {
num = adconv() ;
for(i = 0; i < 32; i++)
{
vBuffer[i]=num/2;
}
LCD__vBuffer32();
LED_A0 = 1;
////////// ClockWise / Acceleration //////////
for(Wi=0; Wi<=1023; Wi++)
{
////2620
CCPR1L = Wi/4 ;
CCPR2L = 0 ;
//////26k22
//CCPR4L = Wi/4 ;
//CCPR5L = 0 ;
__delay_ms(2) ;
}
////////// ClockWise / Deceleration //////////
for(Wi=0; Wi<=1023; Wi++)
{
////2620
CCPR1L = (1023-Wi)/4 ;
CCPR2L = 0 ;
//////26k22
//CCPR4L = (1023-Wi)/4 ;
//CCPR5L = 0 ;
__delay_ms(2) ;
}
/////////////// Breake ////////////////////////
//// 2620
CCPR1L = 255 ;
CCPR2L = 255 ;
////// 26k22
//CCPR4L = 255 ;
//CCPR5L = 255 ;
__delay_ms(250) ;
__delay_ms(250) ;
__delay_ms(250) ;
__delay_ms(250) ;
LED_A0 = 0;
////////// Counter-ClockWise / Acceleration //////////
for(Wi=0; Wi<=1023; Wi++)
{
////2620
CCPR1L = 0 ;
CCPR2L = Wi/4 ;
//////26k22
//CCPR4L = 0 ;
//CCPR5L = Wi/4 ;
__delay_ms(2) ;
}
////////// Counter-ClockWise / Deceleration //////////
for(Wi=0; Wi<=1023; Wi++)
{
////2620
CCPR1L = 0 ;
CCPR2L = (1023-Wi)/4 ;
//////26k22
//CCPR4L = 0 ;
//CCPR5L = (1023-Wi)/4 ;
__delay_ms(2) ;
}
/////////////// Breake ////////////////////////
//// 2620
CCPR1L = 255 ;
CCPR2L = 255 ;
////// 26k22
//CCPR4L = 255 ;
//CCPR5L = 255 ;
__delay_ms(250) ;
__delay_ms(250) ;
__delay_ms(250) ;
__delay_ms(250) ;
}
}
// 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;
}
// ADC function
uint16_t adconv()
{
uint16_t temp;
GO_nDONE = 1 ;
while(GO_nDONE) ;
temp = ADRESH ;
temp = ( temp << 8 ) | ADRESL ;
return temp ;
}
PIC18Fの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);
// ADC function
WORD adconv(void);
#pragma code
void main(void){
//2620
ADCON0 = 0x00; // (2620-E-p223) all A/D Converter disabled
ADCON1 = 0x0F; // (2620-E-p224) A/D Port all Digital
PORTA = 0b00000000 ;
PORTB = 0b00000000 ;
PORTC = 0b00000000 ;
TRISA = 0b00100000 ; // (2620-E-p92) only AN4(RA5) A/D input. not affected by analog input of ADCON1
TRISB = 0b00000000 ;
TRISC = 0b00000000 ;
////26k22
//ANSELA = 0b00100000 ; // (26k22-G-p149) AN4(RA5) Digital input buffer disabled. AN3-AN0 Digital input buffer enabled.
//ANSELB = 0b00000000 ;
//ANSELC = 0b00000000 ;
//PORTA = 0b00000000 ;
//PORTB = 0b00000000 ;
//PORTC = 0b00000000 ;
//TRISA = 0b00100000 ; // (26k22-G-p150) only RA5(AN4) configured as an input (tri-stated).
//TRISB = 0b00000000 ;
//TRISC = 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 and CCP2(RB3) init
CCP1CON = 0b00001100 ;
CCP2CON = 0b00001100 ;
T2CON = 0b00000010 ;
CCPR1L = 0 ;
CCPR1H = 0 ;
CCPR2L = 0 ;
CCPR2H = 0 ;
TMR2 = 0 ;
PR2 = 249 ;
T2CONbits.TMR2ON = 1 ;
////// 26K22 pwm, Standard CCP4 and CCP5 init
//CCPTMRS1 = 0b00000100 ;
//CCP4CON = 0b00001100 ;
//CCP5CON = 0b00001100 ;
//T2CON = 0b00000010 ;
//T4CON = 0b00000010 ;
//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 ;
//// ADC init
ADCON0 = 0b00010001 ;
ADCON1 = 0b00000000 ;
ADCON2 = 0b10010101 ;
Delay10TCYx(5);
//// details
//// 2620 ADC init details, (2620 E-pp223-225)
//ADCON0 = 0b00010001 ; // select AN4(RA5). A/D Converter module is enabled
// ADCON0 — — CHS3 CHS2 CHS1 CHS0 GO/DONE ADON
// 0 0 0 1 0 0 0 1
//ADCON1 = 0b00000000 ; // Vss and Vdd. PCFG<2:0> = 111 by PBADEN = 0 in Confuguration Bits. only AN4(RA5) A/D input by TRISA = 0b00100000, not affected by analog input of ADCON1 (2620-E-p92).
// ADCON1 — — VCFG1 VCFG0 PCFG3 PCFG2 PCFG1 PCFG0
// 0 0 0 0 0 0 0 0
//ADCON2 = 0b10010101 ; // Right justified, Acquisition Time 4Tad, Conversion Clock FOSC/16
// ADCON2 ADFM — ACQT2 ACQT1 ACQT0 ADCS2 ADCS1 ADCS0
// 1 0 0 1 0 1 0 1
//// 26k22 ADC init details, (26k22 G-pp149-152, pp295-298)
//ADCON0 = 0b00010001 ; // select AN4(RA5). A/D Converter module is enabled
// ADCON0 — CHS4 CHS3 CHS2 CHS1 CHS0 GO/DONE ADON
// 0 0 0 1 0 0 0 1
//ADCON1 = 0b00000000 ;
// ADCON1 TRIGSEL — — — PVCFG1 PVCFG0 NVCFG1 NVCFG0
// 0 0 0 0 0 0 0 0
//ADCON2 = 0b10010101 ;
// ADCON2 ADFM — ACQT2 ACQT1 ACQT0 ADCS2 ADCS1 ADCS0
// 1 0 0 1 0 1 0 1
while(1)
{
num = adconv() ;
for(i = 0; i < 32; i++)
{
vBuffer[i]=num/2;
}
LCD__vBuffer32();
LED0_IO = 1;
////////// ClockWise / Acceleration //////////
for(Wi=0; Wi<=1023; Wi++)
{
////2620
CCPR1L = Wi/4 ;
CCPR2L = 0 ;
//////26k22
//CCPR4L = Wi/4 ;
//CCPR5L = 0 ;
Delay10KTCYx(2) ;
}
////////// ClockWise / Deceleration //////////
for(Wi=0; Wi<=1023; Wi++)
{
////2620
CCPR1L = (1023-Wi)/4 ;
CCPR2L = 0 ;
//////26k22
//CCPR4L = (1023-Wi)/4 ;
//CCPR5L = 0 ;
Delay10KTCYx(2) ;
}
/////////////// Breake ////////////////////////
//// 2620
CCPR1L = 255 ;
CCPR2L = 255 ;
////// 26k22
//CCPR4L = 255 ;
//CCPR5L = 255 ;
Delay10KTCYx(250) ;
Delay10KTCYx(250) ;
Delay10KTCYx(250) ;
Delay10KTCYx(250) ;
LED0_IO = 0;
////////// Counter-ClockWise / Acceleration //////////
for(Wi=0; Wi<=1023; Wi++)
{
////2620
CCPR1L = 0 ;
CCPR2L = Wi/4 ;
//////26k22
//CCPR4L = 0 ;
//CCPR5L = Wi/4 ;
Delay10KTCYx(2) ;
}
////////// Counter-ClockWise / Deceleration //////////
for(Wi=0; Wi<=1023; Wi++)
{
////2620
CCPR1L = 0 ;
CCPR2L = (1023-Wi)/4 ;
//////26k22
//CCPR4L = 0 ;
//CCPR5L = (1023-Wi)/4 ;
Delay10KTCYx(2) ;
}
/////////////// Breake ////////////////////////
//// 2620
CCPR1L = 255 ;
CCPR2L = 255 ;
////// 26k22
//CCPR4L = 255 ;
//CCPR5L = 255 ;
Delay10KTCYx(250) ;
Delay10KTCYx(250) ;
Delay10KTCYx(250) ;
Delay10KTCYx(250) ;
}
}
#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;
}
// ADC function
WORD adconv(void)
{
WORD temp;
PIR1bits.ADIF = 0; // clear ADIF, 26k22 datasheet, G-p316
ADCON0bits.GO=1; // begin A/D conv.
while(!PIR1bits.ADIF); // wait for A/D convert complete
temp = ADRESH ;
temp = ( temp << 8 ) | ADRESL ;
return temp ;
}
C18用のHardwareProfile.hとConfiguration Bitsは、2 spi-sramと同じです。