PIC12F675の内蔵クロック周波数のキャリブレーションの方法が分かり、クロック周波数の精度を誤差5%以下に調整できました。
それでは、PIC12F675で、シリアル通信をやってみましょう。PIC12F675は、MSSPなどのデータ通信機能を持っていませんので、プログラムでシリアル通信を実現します。(ソフトウェアUARTといいます)
プログラムは、海外のサイト(Saeed's Blog)を参考にしました。(というかほとんどコピーさせてもらいました)
回路図です。GP0を送信にGP1を受信に使います。
----------------------------------------------------
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
// CONFIG
#pragma config FOSC = INTRCIO // 内蔵クロック4MHz
#pragma config WDTE = OFF
#pragma config PWRTE = ON
#pragma config MCLRE = OFF
#pragma config BOREN = OFF
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config FOSC = INTRCIO // 内蔵クロック4MHz
#pragma config WDTE = OFF
#pragma config PWRTE = ON
#pragma config MCLRE = OFF
#pragma config BOREN = OFF
#pragma config CP = OFF
#pragma config CPD = OFF
#define _XTAL_FREQ 4000000
#define Baudrate 1200
#define OneBitDelay (1000000 / Baudrate)
#define HalfBitDelay (1000000 / Baudrate / 2)
#define TX GP0
#define RX GP1
#define Baudrate 1200
#define OneBitDelay (1000000 / Baudrate)
#define HalfBitDelay (1000000 / Baudrate / 2)
#define TX GP0
#define RX GP1
//シリアル通信ポートの初期化
void serial_init(){
TRISIO0 = 0; //GP0 output
TRISIO1 = 1; //GP1 input
TX = 1; //アイドル状態でTXpin High
}
TRISIO0 = 0; //GP0 output
TRISIO1 = 1; //GP1 input
TX = 1; //アイドル状態でTXpin High
}
//1文字送信
void putch(unsigned char byte){
// Send start bit
TX = 0;
__delay_us(OneBitDelay);
for(unsigned char i=0;i<8;i++){
if((byte >> i)&0x1){
TX = 1;
}else{
TX = 0;
}
__delay_us(OneBitDelay);
}
//Send stop bit
TX = 1;
__delay_us(OneBitDelay);
}
// Send start bit
TX = 0;
__delay_us(OneBitDelay);
for(unsigned char i=0;i<8;i++){
if((byte >> i)&0x1){
TX = 1;
}else{
TX = 0;
}
__delay_us(OneBitDelay);
}
//Send stop bit
TX = 1;
__delay_us(OneBitDelay);
}
//1文字受信
unsigned char getch(){
unsigned char RCdata = 0;
while(RX == 1); //wait for start bit
__delay_us(OneBitDelay);
__delay_us(HalfBitDelay);
for(unsigned char i=0;i<8;i++){
if(RX == 1){
RCdata += (1<<i);
}
__delay_us(OneBitDelay);
}
if(RX == 1){
__delay_us(OneBitDelay);
return RCdata;
}else{
__delay_us(OneBitDelay);
return 0x00;
}
}
unsigned char RCdata = 0;
while(RX == 1); //wait for start bit
__delay_us(OneBitDelay);
__delay_us(HalfBitDelay);
for(unsigned char i=0;i<8;i++){
if(RX == 1){
RCdata += (1<<i);
}
__delay_us(OneBitDelay);
}
if(RX == 1){
__delay_us(OneBitDelay);
return RCdata;
}else{
__delay_us(OneBitDelay);
return 0x00;
}
}
//メインプログラム
void main() {
unsigned char ch;
CMCON = 0x07; //comparater OFF
ANSEL = 0x00; //All GPIO is digital I/O
TRISIO = 0b00001000; //GP3 is input otheris outpiut
GPIO = 0x00; // clear I/O port
serial_init(); // UART initialize
while(1){
ch = getch(); //1文字受信
putch(ch); //1文字送信
}
}
unsigned char ch;
CMCON = 0x07; //comparater OFF
ANSEL = 0x00; //All GPIO is digital I/O
TRISIO = 0b00001000; //GP3 is input otheris outpiut
GPIO = 0x00; // clear I/O port
serial_init(); // UART initialize
while(1){
ch = getch(); //1文字受信
putch(ch); //1文字送信
}
}
--------------------------------------------
TeraTermで送受信した画面です。
通信速度2400bps,4800bpsとあげて、テストしてみましたが、文字化けしてしまいました。
OnebitDelayの数値を調整すれば、速度アップもできると思いますが、とりあえず、シリアル通信でデータを送信したいときには、1200bpsと速度は遅いですが、このプログラムで送受信できます。