fc2ブログ

4桁7セグで遊ぶ(2)

 今回も前回に引き続いて、PICを用いて4桁7セグで遊びました。PCからシリアル通信でPIC側に指令を出し、その指令に基づいて7セグを制御しました。PICのシリアル通信(USART通信)の割り込み処理部分の理解に苦しみ、手こずってしまいました・・。
 PIC側の基板は写真の通りで、USART用ピンとI2C(SPI)用ピンを追加配線しました。PIC基板170226
PIC_7seg制御回路図170226
 プログラムは、前回のプログラムにUSART通信部分を追加する形で進めましたが、7セグ表示と同居すると、通信がうまく行かなかったり、表示がうまく行かなかったりと難儀しました。割り込みがうまく行っていないのかなとも考え、深みにはまっていました。最終的には、このサイトのライブラリ類(skUARTlib.c、skUARTlib.h)を参考にさせていただくことでうまく行きました。大変感謝です・・。

//----------------------------------------------
// 7seg control program for PIC16F873A
//----------------------------------------------

// CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "skUARTlib.h"

#define _XTAL_FREQ 20000000 /* for delay use */
#define UART_RX_SIZE 5

char rbuf[8];
char sbuf[8];
char cdig[2];
int i, n;
int idig[5];

//segment character
const unsigned char cSeg[11] = {
// .GFEDCBA // pattern
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00100111, // 7
0b01111111, // 8
0b01101111, // 9
0b10000000 // period
};

//dot character
const unsigned char cDot[8]={
0b00000000, //OFF
0b00000001, //D1
0b00000010, //D2
0b00000011, //D1+D2
0b00000100, //D3
0b00000101, //D1+D3
0b00000110, //D2+D3
0b00000111, //D1+D2+D3
};

//initialize PIC
void InitPic(void)
{
//PortA
// bit0:RA0 2 Out(0) DEG1 COM
// bit1:RA1 3 Out(0) DEG2 COM
// bit2:RA2 4 Out(0) DEG3 COM
// bit3:RA3 5 Out(0) DEG4 COM
// bit4:RA4 6 Out(0)
// bit5:RA5 7 Out(0) DEG5 COM
// bit6:RA6 - Out(0)
// bit7:RA7 - Out(0)
TRISA = 0b00000000;

//PortB
// bit0:RB0 21 Out(0) SEG A
// bit1:RB1 22 Out(0) SEG B
// bit2:RB2 23 Out(0) SEG C
// bit3:RB3 24 Out(0) SEG D
// bit4:RB4 25 Out(0) SEG E
// bit5:RB5 26 Out(0) SEG F
// bit6:RB6 27 Out(0) SEG G
// bit7:RB7 28 Out(0) SEG DP
TRISB = 0b00000000;

//PortC
// bit0:RC0 11 Out(0)
// bit1:RC1 12 Out(0)
// bit2:RC2 13 Out(0)
// bit3:RC3 14 Out(0)
// bit4:RC4 15 Out(0)
// bit5:RC5 16 Out(0)
// bit6:RC6 17 Out(0) TX
// bit7:RC7 18 IN(1) RX
TRISC = 0b10000000;

//IO Initialize
PORTA = 0b00000000;
PORTB = 0b00000000;
PORTC = 0b00000000;
}

//interrupt
void interrupt InterFunction(void){
InterUART(); // USARTの受信割り込み
}

//7seg digit set
void SetDigit(int dg1,int dg2,int dg3,int dg4,int dot){

RA0=1;
PORTB=cSeg[dg1];
__delay_ms(1);
RA0=0;
PORTB = 0b00000000;

RA1=1;
PORTB=cSeg[dg2];
__delay_ms(1);
RA1=0;
PORTB = 0b00000000;

RA2=1;
PORTB=cSeg[dg3];
__delay_ms(1);
RA2=0;
PORTB = 0b00000000;

RA3=1;
PORTB=cSeg[dg4];
__delay_ms(1);
RA3=0;
PORTB = 0b00000000;

RA5=1;
PORTB=cDot[dot];
__delay_ms(1);
RA5=0;
PORTB = 0b00000000;

}

//wait
void Wait(int num){
do{
__delay_ms(10);
}while(--num>0);
}

//main
void main(void){

InitPic();

//USART初期化(8bit,StopBit:1, No Parity, No flow,19200bps)
InitUART(64);

while(1){
//受信待ち
if (UART_Available() != 0) {
//データ受信
n = 0;
memset(rbuf,0,strlen(rbuf));//データバッファ初期化
while(UART_Available() != 0) {
rbuf[n] = UART_Read();//受信
n++;
Wait(1);
}

//データ送信(確認用)
i=0;
memset(sbuf,0,strlen(sbuf));//データバッファ初期化
while(i
sbuf[i] = rbuf[i];
i++;
}
sbuf[i] = 0x0d;//CR
sbuf[i+1] = 0x0a;//LF
UART_Send(sbuf,n+2);//送信

UART_Flush();//受信バッファクリア

for(int i=0;i<5;i++){
memset(cdig,0,strlen(cdig));//初期化
strncpy(cdig,sbuf+i,1); //1文字抽出
cdig[1]='\0';
idig[i]=atoi(cdig);
}
}
//表示
SetDigit(idig[0],idig[1],idig[2],idig[3],idig[4]);
}
}
 106, 157, 161, 165, 166, 180, 182行目のUART関連の命令は、ライブラリ類(skUARTlib.c、skUARTlib.h)の関数です。
 TeraTermを起動し、以下の設定をしました。teraterm設定画面1_170226teraterm設定画面2_170226 PCとのシリアル通信は、以前のブログで紹介したMAX3232ECPEを用いた信号変換基板を使用しています。ターミナルから「12345」のデータを送信した結果、設計通りの結果が表示されました。5文字目の5は、ドットのD1とD3を表示する指令です。res_1234_170226.png続いて、「67891」と「22222」のデータを送信しても、正しく表示されました。teraterm実行画面_170226res_6789_170226.pngres_2222_170226.png 苦労しましたが、やっとここまで来ることが出来ました。次は、PICを用いて、「温湿度、気圧センサ」のデータを取り込んでみようと思います。
スポンサーサイト



コメント

非公開コメント

ご訪問者数

(Since 24 July, 2016)

タグクラウド


プロフィール

Dr.BobT

Author: Dr.BobT
興味のおもむくままに生涯考え続けるエンジニアでありたい。

月別アーカイブ

メールフォーム

名前:
メール:
件名:
本文: