PICを使ったUSART通信

閑話休題。
仕事でちょいと必要になったので、この週末はPICを使ってUSART通信の実験をしました。
おおむね思い通りに動くようになったので、防備録としておいておきます。
仕事がらみなので、写真は無しの方向で。

それから、11/23日の金曜日は ニコニコ技術部吸収勉強会3 にCNCステージ持って参加してきました。参加者は30人くらいかな。結構な盛り上がりで楽しかったです。
もうすぐ動画がうPされるはず。

と言うことで、ソース。

******************main関数部**********************

//
// compiler: MPLAB XC8 Compiler
// 2012/11/24

// Configration
// RA0: RS for LCD
// RA1: read/write for LCD
// RA2: enable for LCD
// RB1: RX
// RB2: TX
// RB4-7: LCD data port

#include <pic.h>
#include <stdio.h>
#include “lcd.h”

#define _XTAL_FREQ  8000000
#define interval 200 // set here checking interval

__CONFIG(CLKOUTEN_OFF & FOSC_INTOSC & FCMEN_OFF & IESO_OFF & BOREN_ON &
                PWRTE_ON & WDTE_OFF & MCLRE_OFF & CP_OFF & CPD_OFF) ;
__CONFIG(PLLEN_ON & STVREN_ON & WRT_OFF & BORV_HI & LVP_OFF);

void putch(unsigned char); // defined function by printf
unsigned char TxData[16]; // data buffer for quotation
unsigned char RxData[20]; // data buffer for receive
char cnt; // variable for for-loop
char rcnt=0; // variable for receiving data count
char Lcd1Serial0=1; // switch for controling out put way
char Power; // for bar graph

void putch(unsigned char tx_data)
{
if(Lcd1Serial0)lcd_putch(tx_data);
else
{
while(!TXIF); // sending quotation via serial
TXREG=tx_data;
}
}

void interrupt ReceiveData()
{
if (RCIF == 1) // confirm USART interruption
{
RxData[rcnt] = RCREG; // receive data
RCIF = 0; // rest flag
}
rcnt++; // increment
}
void main()
{
    OSCCON=0b01110010; // internal clock 8MHz
    ANSELA=0b00000000; // No analog for PORTA
    ANSELB=0b00000000; // No analog for PORTB
    TRISA=0b00100000; // Set I/O according to configuration
    TRISB=0b00000010; // Set I/O according to configuration
    PORTA=0b00000000; // reset out put
    PORTB=0b00000000; // reset out put

lcd_init(); // initialize LCD screen
//__delay_ms(1000);

//Lcd1Serial0=1;
//printf(“connection”);
//lcd_goto(0x40);
//printf(”   checker”);
//__delay_ms(3000);
//lcd_clear();

コマンド部分は削除 ^^;

TXSTA  = 0b00100100 ; // asynchronous, 8bit, no-parity bit
RCSTA  = 0b10010000 ; // serial port enable, continuous receive enable
SPBRG  = 25; // baud rate 19200 error 0.16%
RCIF = 0; // reset USART interruption flag
RCIE = 1; // enable USART interruption
PEIE = 1; // enable peripheral interruntion

GIE  = 1; // enable general interruntion

while(1)
{
Lcd1Serial0=0;
for(cnt=0; cnt<=15; cnt++)putch(TxData[cnt]); // quotation
Lcd1Serial0=1;
lcd_goto(0x40);
printf(“.”); // show checking indicator

__delay_ms(interval);
//lcd_clear();
if(rcnt>=19)
{
Power=(RxData[12]-16)/3; // ignore low level & set number of bar
if((Power<=2) | (Power>=65))Power=0; // ignore low level

lcd_goto(0x40);
printf(” “); // erase “.”
lcd_goto(0x00);
printf(”                “); // erase bars
lcd_goto(0x00);
for(cnt=0; cnt<=(Power); cnt++)putch(0xFF); // renew bars

if(RxData[12]<=0x03)RxData[12]=0x00; // ignore low level
lcd_goto(0x4E);
printf(”  “); // erase number
lcd_goto(0x4E);
printf(“%d”,RxData[12]); // show received data in number
rcnt=0;
}
__delay_ms(interval);
}
}
***********************LCD.c**************************

#define _XTAL_FREQ 8000000
#include <htc.h>
#include “lcd.h”

#define LCD_RS RA0
#define LCD_RW RA1
#define LCD_EN RA2

#define LCD_DATA PORTB

#define LCD_STROBE() ((LCD_EN = 1),(LCD_EN=0))

/* write a byte to the LCD in 4 bit mode */

void
lcd_write(unsigned char c)
{
__delay_us(40);
LCD_DATA = ( c & 0xF0 );
LCD_STROBE();
LCD_DATA = ( ( c << 4 ) & 0xF0 );
LCD_STROBE();
}

/*
 * Clear and home the LCD
 */

void
lcd_clear(void)
{
LCD_RS = 0;
lcd_write(0x01);
__delay_ms(2);
}

/* write a string of chars to the LCD */

void
lcd_puts(const char * s)
{
LCD_RS = 1; // write characters
while(*s)
lcd_write(*s++);
}

/* write one character to the LCD */

void
lcd_putch(char c)
{
LCD_RS = 1; // write characters
lcd_write( c );
}

/*
 * Go to the specified position
 */

void
lcd_goto(unsigned char pos)
{
LCD_RS = 0;
lcd_write(0x80+pos);
}

/* initialise the LCD – put into 4 bit mode */
void
lcd_init()
{
char init_value;

init_value = 0b00110000;

LCD_RS = 0;
LCD_EN = 0;
LCD_RW = 0;

__delay_ms(15); // wait 15mSec after power applied,
LCD_DATA = init_value;
LCD_STROBE();
__delay_ms(5);
LCD_STROBE();
__delay_us(200);
LCD_STROBE();
__delay_us(200);
LCD_DATA = 0b00100000; // Four bit mode
LCD_STROBE();

lcd_write(0x28); // Set interface length
lcd_write(0xC); // Display On, Cursor OFF, Cursor Blink OFF
lcd_clear(); // Clear screen
lcd_write(0x6); // Set entry Mode
}
*********************LCD.h************************

/* write a byte to the LCD in 4 bit mode */

extern void lcd_write(unsigned char);

/* Clear and home the LCD */

extern void lcd_clear(void);

/* write a string of characters to the LCD */

extern void lcd_puts(const char * s);

/* Go to the specified position */

extern void lcd_goto(unsigned char pos);

/* intialize the LCD – call before anything else */

extern void lcd_init(void);

extern void lcd_putch(char);

/* Set the cursor position */

#define lcd_cursor(x) lcd_write(((x)&0x7F)|0x80)

******************************************************
以上。

コメント