MicroController Design -- Centronic Printer and Greedy Snake
2012-03-27 10:55 wihoho 阅读(475) 评论(0) 编辑 收藏 举报其实还有有些不开心的,这门课最后居然只demo了10几分钟,我在拆板子的线的时候觉得特别特别不爽,就像你有付出的东西没得到回报一样,不过无所谓啦,也许真的只是为了寻求一种感觉,我们的生活不也是这样子吗?虽然最近大概没有做好什么事情,不过,不管啦。哈哈!我会做得越来越好的,现在备份下代码吧,或许我再也不会接触了。
keypad.c
/***********************************************************************/
/**/
/* FILE :keypad.c */
/* DATE :Fri, Feb 17, 2012 */
/* DESCRIPTION :Main Program */
/* CPU TYPE :H8S/2377R */
/**/
/* This file is generated by Renesas Project Generator (Ver.4.5). */
/**/
/***********************************************************************/
#include "Snake.c"
void Scan_Keypad();
void Port2P4_Interrupt_Settings();
void initSerial(void);
void sendSerial(char dataByte);
void writeSerialISR();
void sendString(char dataString[]);
void ini_IO_KeyPad();
void Print();
void ini_menu();
void SnakeInit();
void init_TPU3();
static int keyDebounceSeq = 0; // Used to indicate the sequence of IRQ12
static char KeyPressed = '.'; // Used to record the pressed key
static int mode = 0; //0 means current LCD shows the menu
//1 means the printer mode
//2 means the snake game mode
//Below are for SCI
static char readData;
char gSerialBuffer[100];
int pointer = 0;
int length = 0;
//Below are for printing
static char dataBuffer[1000];
static int gWhichChar = 0;
static int gBufLen = 0;
void Toggle_P21(){
P2.DR.BIT.B1 = 0;
P2.DR.BIT.B1 = 1;
}
void ini_IO_KeyPad(){
P8.DDR = 0x38; //initialize P83, P84 and P85 as outputs
P8.DR.BYTE = 0x00; //initial value are ooo
//P9 pins all are input pins, therefore no need to define
}
//.................................IRQ12......................................./
void Port2P4_Interrupt_Settings(){
INTC.ITSR.BIT.ITS12 = 1;
INTC.ISCR.BIT.IRQ12SC = 1;
INTC.IER.BIT.IRQ12E = 1;
}
void IRQ12_Interrupt_Handler(){
P2.DR.BIT.B3 = 0;
INTC.ISR.BIT.IRQ12F = 0; //Clearing the interrupt set flag
TPU.TSTR.BIT.CST1 = 1; //Start the timer
//INTC.IER.BIT.IRQ12E = 0; //Disable the IRQ12 for 10ms
P2.DR.BIT.B3 = 1;
}
//..................................TPU......................................./
void init_TPU1()
{
MSTPCR.BIT._TPU=0;
TPU1.TCR.BYTE=0x23; // clock/64
TPU1.TMDR.BYTE=0x00;
TPU1.TIOR.BIT.IOA=0x07; //initial output is 1, toggle when match
TPU1.TIOR.BIT.IOB=0x00;
TPU1.TIER.BIT.TGIEA=1;
TPU1.TGRA=1225; //Set 10ms delay
TPU1.TCNT=0;
}
void TPU1_handler(){
P2.DR.BIT.B6 = 0;
TPU1.TSR.BIT.TGFA = 0;
TPU.TSTR.BIT.CST1 = 0; // Stop the timer
if(keyDebounceSeq == 0){
if(P2.PORT.BIT.B4 == 0){
Scan_Keypad();
INTC.ISCR.BIT.IRQ12SC = 2; //Rise IRQ12 at the rising edge
keyDebounceSeq = 1;
}
}
else{
INTC.ISCR.BIT.IRQ12SC = 1; //Rise IRQ12 at the falling edge
keyDebounceSeq = 0;
}
P2.DR.BIT.B6 = 1;
}
//....................................Scan Keypad........................./
void Scan_Keypad(){
P2.DR.BIT.B5 = 0;
P8.DR.BYTE = 0x30;
if(P9.PORT.BIT.B0 == 0){
//row 1 col 1
KeyPressed='1';
}
else if(P9.PORT.BIT.B1 == 0)
//row 2 col 1
KeyPressed= '4';
else if(P9.PORT.BIT.B2== 0)
//row 3 col 1
KeyPressed='7';
else if(P9.PORT.BIT.B3== 0)
//row 4 col 1
KeyPressed='*';
P8.DR.BYTE = 0x28;
if(P9.PORT.BIT.B0 == 0)
//row 1 col 1
KeyPressed='2';
else if(P9.PORT.BIT.B1 == 0)
//row 2 col 1
KeyPressed= '5';
else if(P9.PORT.BIT.B2== 0)
//row 3 col 1
KeyPressed='8';
else if(P9.PORT.BIT.B3== 0)
//row 4 col 1
KeyPressed='0';
P8.DR.BYTE = 0x18;
if(P9.PORT.BIT.B0 == 0)
//row 1 col 1
KeyPressed='3';
else if(P9.PORT.BIT.B1 == 0)
//row 2 col 1
KeyPressed= '6';
else if(P9.PORT.BIT.B2== 0)
//row 3 col 1
KeyPressed='9';
else if(P9.PORT.BIT.B3== 0)
//row 4 col 1
KeyPressed='#';
sendSerial(KeyPressed);
if(mode == 0){
if(KeyPressed == '1'){
mode = 1;
LCD_SetColor(LCD_StandardColor(0));
LCD_FillRect(0,0,128,160);
LCD_SetColor(LCD_StandardColor(15));
LCD_DrawString("You now can send chars or ",5,50);
LCD_DrawString("chars or send file ",5,70);
LCD_DrawString("to the printer ",5,90);
}
else if(KeyPressed == '2'){
mode = 2;
init_TPU3(); //initialize the TPU3 for snake game
SnakeInit(); // initialize the snake game
}
}
else if(mode == 1){
if(KeyPressed == '0'){
mode = 0;
ini_menu();
}
}
else if(mode == 2){
if(KeyPressed == '2') {
if(direction != 4)
direction = 1;
}
else if(KeyPressed == '4'){
if(direction != 3)
direction = 2;
}
else if(KeyPressed == '6'){
if(direction != 2)
direction = 3;
}
else if(KeyPressed == '5') {
if(direction != 1)
direction = 4;
}
else if(KeyPressed == '*') {
TPU.TSTR.BIT.CST3 = 0; //Pause is achieved by stopping the timer
}
else if(KeyPressed == '#'){
TPU.TSTR.BIT.CST3 = 1; //Resume
}
else if(KeyPressed == '0'){
mode = 0;
TPU.TSTR.BIT.CST3 = 0;
ini_menu();
}
}
P8.DR.BYTE = 0x00;//Set pins as 0
P2.DR.BIT.B5 = 1;
}
//...........................................SCI................................./
void initSerial(void){
unsigned short delay;
MSTPCR.BIT._SCI1 = 0;
SCI1.SCMR.BIT.SMIF = 0;
SCI1.SCR.BIT.TE = 0;
SCI1.SCR.BIT.RE = 0;
SCI1.SCR.BIT.CKE = 0x00;
//Serial Mode Register (SMR)
//Bit 7: C/A_N = 0 -> Asynchronous Mode
//Bit 6: CHR = 0 -> Data length = 8 bits
//Bit 5: PE = 0 -> disable parity
//Bit 4: O/E_N = 0 -> odd parity
//Bit 3: STOP = 0 -> 1 stop bit
//Bit 2: MP = 0 -> Disable multiprocessor mode
//Bit 1: CKS1 = 0 -> Select phi as clock source, n = 0
//Bit 0: CKS0 = 0
SCI1.SMR.BYTE = 0x00;
SCI1.BRR = 25; //9600 baud rate
//minimun 1 bit interval
for (delay = 0; delay < 1000; delay++)
{ }
SCI1.SCR.BIT.TE = 1;
SCI1.SCR.BIT.RE = 1;
SCI1.SCR.BIT.RIE = 1;
}
//........................Revised SCI module..................
char readSerialISR(){
P3.DR.BIT.B0 = 0;
readData = SCI1.RDR;
SCI1.SSR.BIT.RDRF = 0;
if(gBufLen == 0){
dataBuffer[gBufLen++] = readData;
Print();
TPU.TSTR.BIT.CST0 = 1; //Star the timer to measure the speed
}
else if(gBufLen < 1000)
dataBuffer[gBufLen++] = readData;
//Second method --- real circular buffer
/*
if(gBufLen == 0){
dataBuffer[gBufLen++] = readData;
Print();
TPU.TSTR.BIT.CST0 = 1; //Star the timer to measure the speed
sendString("The buffer is 1\n");
}
else if(gBufLen < 1000){
dataBuffer[gBufLen++] = readData;
sendString("The buffer is less than 1000\n");
}
else{
if(gBufLen%1000 < gWhichChar%1000){
dataBuffer[(gBufLen++)%1000] = readData;
sendString("The buffer size is bigger than 1000\n");
}
else{
sendString("Some characters are lost because the buffer is full!\n");
}
}*/
P3.DR.BIT.B0 = 1;
return readData;
}
void sendSerial(char dataByte){
gSerialBuffer[length++] = dataByte;
SCI1.SCR.BIT.TIE = 1; //Enable transimitting interrupt
}
void writeSerialISR(){
P3.DR.BIT.B2 = 0;
if(pointer < length)
SCI1.TDR = gSerialBuffer[pointer++];
if(pointer >= length){
SCI1.SCR.BIT.TIE = 0; //Disable transimitting interrupt since no data is needed to send
pointer = 0;
length = 0;
}
SCI1.SSR.BIT.TDRE = 0; //Clear TDRE flag
P3.DR.BIT.B2 = 1;
return;
}
void sendString(char dataString[]){
int x = 0;
while(dataString[x]!= '\0'){
sendSerial(dataString[x]);
x++;
}
}
/*void sendSerial(char dataByte){
char wait = 1;
unsigned char canSend;
P2.DR.BIT.B3 = 1;
while(wait){
canSend = SCI1.SSR.BIT.TDRE;
if(canSend == 1)
wait = 0;
}
SCI1.TDR = dataByte;
SCI1.SSR.BIT.TDRE = 0;
P2.DR.BIT.B3 = 0;
return;
}
char readSerialISR(){
// readData = SCI1.RDR;
// SCI1.SSR.BIT.RDRF = 0;
// sendSerial(readData);
// Print(readData);
// return readData;
readData = SCI1.RDR;
SCI1.SSR.BIT.RDRF = 0;
sendSerial(readData);
if(gBufLen == 0){
dataBuffer[gBufLen++] = readData;
Print();
TPU.TSTR.BIT.CST0 = 1; //Star the timer to measure the speed
}
else
dataBuffer[gBufLen++] = readData;
}
void sendSring(char dataString[]){
int x = 0;
while(dataString[x]!= '\0'){
sendSerial(dataString[x]);
x++;
}
}
*/
Printer.c
/***********************************************************************/
/**/
/* FILE :Printer.c */
/* DATE :Thu, Feb 23, 2012 */
/* DESCRIPTION :Main Program */
/* CPU TYPE :H8S/2377R */
/**/
/* This file is generated by Renesas Project Generator (Ver.4.5). */
/**/
/***********************************************************************/
#include "iodefine.h"
#include "stdio.h"
#include "keypad.c"
void ini_IO_Printer();
void Port5P0_Interrupt_Setting();
void IRQ0_Interrupt_Handler();
void Print();
void init_TPU0();
void TPU0_handler();
void IRQ1_Interrupr_handler();
void Port5P1_Interrupt_Setting();
static int index = 0; //TPU2 generates an interrupt after 0.5 us when index = 0
static int counter = 0; //TPU0 used this item to calculate the speed after 20*0.0625 = 1.25s
static int numOfchar = -1; //counts the printed characters every 1.25s
static int numOfprinted = -1; //counts the printed characters so far
float speed; //Hold the value of speed
char cVal[32]; //Hold the chars converted from the float type speed
int i; //Used as counter to send data to PC
void ini_IO_Printer(){
P1.DDR = 0xff;
P6.DDR = 0xf0;
P5.DDR = 0x00;
P3.DDR = 0xff;
P2.DDR = 0xEF;
P1.DR.BYTE = 0x00;
}
//............................IRQ0 generated by ACK ....................//
void Port5P0_Interrupt_Setting(){
INTC.ITSR.BIT.ITS0 = 0; //Choose P50 as IRQ0 input pin
INTC.ISCR.BIT.IRQ0SC = 1; //Generate interrupts at the falling edge
INTC.IER.BIT.IRQ0E = 1; //Enable the IRQ0 interrupr request
}
void IRQ0_Interrupt_Handler(){
P2.DR.BIT.B0 = 1; //P20 is used as the indicator of IRQ0
INTC.ISR.BIT.IRQ0F = 0; //Clear the interrupt request flag
numOfprinted ++;
numOfchar ++; //increase the number
P2.DR.BIT.B0 = 0;
}
//...........................IRQ1 generated by BUSY.....................//
void Port5P1_Interrupt_Setting(){
INTC.ITSR.BIT.ITS1 = 0; //Choose P51 as IRQ1 input pin
INTC.ISCR.BIT.IRQ1SC = 2; //Generate interrupt at the rising edge
INTC.IER.BIT.IRQ1E = 1; // Enable the IRQ1 interrupr request
}
void IRQ1_Interrupr_handler(){
P2.DR.BIT.B2 = 1; //P22 is used as the indicator of IRQ1
INTC.ISR.BIT.IRQ1F = 0; //Clear the interrupt request flag
Print();
P2.DR.BIT.B2 = 0;
}
//..............................Print.................//
void Print(){
//This point may be changed to use polling
//while(P6.PORT.BIT.B1 == 0){}
//if(P6.PORT.BIT.B1 == 1){
if(gWhichChar < gBufLen){
TPU0.TIOR.BIT.IOA=0x00;
TPU1.TIOR.BIT.IOA=0x00;
TPU3.TIOR.BIT.IOA =0x00;
P1.DR.BYTE = dataBuffer[gWhichChar++];
sendSerial(P1.DR.BYTE);
P6.DR.BIT.B4 = 1;
P6.DR.BIT.B4 = 0;
TPU0.TIOR.BIT.IOA=0x07;
TPU1.TIOR.BIT.IOA=0x07;
TPU3.TIOR.BIT.IOA = 0x07;
}
if(gWhichChar >= gBufLen){
gWhichChar = 0;
gBufLen = 0;
}
P1.DR.BYTE = 0x00;
}
//...............................TPU0 used for calculating the speed of printing..........//
void init_TPU0()
{
MSTPCR.BIT._TPU=0;
TPU0.TCR.BYTE=0x23; // clock / 64
TPU0.TMDR.BYTE=0x00;
TPU0.TIOR.BIT.IOA=0x07; //initial output is 1, toggle when match
TPU0.TIOR.BIT.IOB=0x00;
TPU0.TIER.BIT.TGIEA=1;
TPU0.TGRA = 8190; //Set 0.0625s delay
TPU0.TCNT=0;
}
void TPU0_handler(){
P2.DR.BIT.B5 = 0;
TPU0.TSR.BIT.TGFA = 0; //Clearing the flag
//TPU.TSTR.BIT.CST0 = 0; //Stop the timer
counter ++;
//After 1.25s
if(counter == 20){
counter = 0;
//Send the speed back
speed = numOfchar/1.25;
sprintf(cVal,"%f",speed);
sendString("Current speed:");
for(i = 0; i < 32; i ++){
if(cVal[i] == '\0')
break;
sendSerial(cVal[i]); //Send the speed
}
numOfchar = 0;
sendSerial('\n');
sendString("Number of printed char: ");
//Send the printed characters back
sprintf(cVal,"%d",numOfprinted);
for(i = 0; i < 32; i ++){
if(cVal[i] == '\0')
break;
sendSerial(cVal[i]); //Send the number of printed characters
}
sendSerial('\n');
}
P2.DR.BIT.B5 = 1;
}
Snake.c
#include "stdlib.h"
void meetNut();
void generateNut();
void update_Snake();
int checkNut();
void SnakeInit();
static int length;
static int head,tail;
static int i;
static const int unit = 8;
static int direction,nextX,nextY;
static int lineX[300],lineY[300];
int foodx = 0, foody = 0;
static int score = 0, level = 1;
void SnakeInit(){
length = 3;
head = 2;
tail = 0;
direction = 1;
generateNut();
//Print the menu on LCD
LCD_SetColor(LCD_StandardColor(15));
LCD_FillRect(0,128,128,32);
LCD_SetColor(LCD_StandardColor(0));
LCD_FillRect(0,0,128,128);
LCD_SetColor(LCD_StandardColor(4));
LCD_FillRect(0,127,128,2);
LCD_SetColor(LCD_StandardColor(0));
LCD_DrawString("Greedy Snake",10,133);
LCD_DrawString("Score: ",20,143);
LCD_DrawString("Level: ",20,153);
LCD_DrawInt(score,80,143);
LCD_DrawInt(level,80,153);
//LCD_FillRect(pointsx[tail],pointsy[tail],length*unit,unit);
//Paint the initialization of the snake
LCD_SetColor(LCD_StandardColor(15));
LCD_FillRect(40,48,8,24);
//Initialize the snake components
lineX[0] = 5; lineY[0] = 8;
lineX[1] = 5; lineY[1] = 7;
lineX[2] = 5; lineY[2] = 6;
generateNut();
}
void generateNut(){
do{
foodx = rand()%16;
foody = rand()%16;
} while(checkNut());
LCD_SetColor(LCD_StandardColor(14));
LCD_FillRect(foodx*unit,foody*unit,unit,unit);
}
int checkNut(){
for(i = tail; i++; i<head+1){
if(foodx == lineX[i] && foody == lineY[i])
return 1;
}
return 0;
}
void update_Snake(){
//Delete the tail unit
LCD_SetColor(LCD_StandardColor(0));
LCD_FillRect(lineX[tail]*unit,lineY[tail]*unit,unit,unit);
//Update the tail and head
tail += 1;
head += 1;
//Update the head drawing component
//1 upward
if(direction == 1){
lineX[head] = lineX[head -1];
lineY[head] = lineY[head -1] -1;
}
//2 leftward
else if(direction == 2){
lineX[head] = lineX[head -1] -1;
lineY[head] = lineY[head -1];
}
//3 rightward
else if(direction == 3){
lineX[head] = lineX[head -1]+1;
lineY[head] = lineY[head -1];
}
//4 downward
else{
lineX[head] = lineX[head -1];
lineY[head] = lineY[head -1] +1 ;
}
LCD_SetColor(LCD_StandardColor(15));
LCD_FillRect(lineX[head]*unit,lineY[head]*unit,unit,unit);
}
void meetNut(){
//Update the drawing of snake
length ++;
head ++;
lineX[head] = foodx;
lineY[head] = foody;
LCD_SetColor(LCD_StandardColor(15));
LCD_FillRect(lineX[head]*unit,lineY[head]*unit,unit,unit);
//Generate new nut
generateNut();
//Update the score and level;
score ++;
if(length == 10) level = 2;
else if(length == 20) level = 3;
else if(length == 30) level = 4;
else if (length == 40) level = 5;
LCD_SetColor(LCD_StandardColor(15));
LCD_FillRect(0,128,128,32);
LCD_SetColor(LCD_StandardColor(0));
LCD_DrawString("Greedy Snake",10,133);
LCD_DrawString("Score: ",20,143);
LCD_DrawString("Level: ",20,153);
LCD_DrawInt(score,80,143);
LCD_DrawInt(level,80,153);
if(level == 4) {
LCD_SetColor(LCD_StandardColor(15));
LCD_FillRect(0,128,128,32);
LCD_SetColor(LCD_StandardColor(0));
LCD_DrawString("You win!",10,133);
LCD_DrawString("Score: ",20,143);
LCD_DrawString("Level: ",20,153);
LCD_DrawInt(score,80,143);
LCD_DrawInt(level,80,153);
TPU.TSTR.BIT.CST3 = 0; // Stop the timer because I already win
}
}
Project.c
/***********************************************************************/
/**/
/* FILE :LCDTest.c */
/* DATE :Thu, Aug 30, 2007 */
/* DESCRIPTION :Main Program */
/* CPU TYPE :H8S/2377R */
/**/
/* This file is generated by Renesas Project Generator (Ver.4.5). */
/**/
/***********************************************************************/
#include "Printer.c"
void ini_menu();
void init_TPU3();
static int temp = 0;
static int twenty = 0;
void main(){
initSerial(); //initialize the SCI
ini_IO_Printer(); //initialize IO pins related with printing
Port5P0_Interrupt_Setting(); //IRQ0 setting
Port5P1_Interrupt_Setting(); //IRQ1 setting
init_TPU0(); //initialize TPU0 for measuring the speed
ini_IO_KeyPad(); //initialize keypad related pins
init_TPU1(); //initialize TPU1 to debounce
Port2P4_Interrupt_Settings(); //P24 is used to generate interrupt when press the keypad
LCD_Init(); //initialize the LCD
ini_menu();
while(1){
P2.DR.BIT.B1 = 1; //P21 is used to monitor the main program
P2.DR.BIT.B1 = 0;
}
}
void ini_menu(){
LCD_SetColor(LCD_StandardColor(15));
LCD_FillRect(0,0,128,160);
LCD_SetColor(LCD_StandardColor(0));
LCD_DrawString("1. Printer ",10,50);
LCD_DrawString("2. Greedy Snake",10,70);
}
void init_TPU3(){
MSTPCR.BIT._TPU = 0;
TPU3.TCR.BYTE = 0x23;
TPU3.TMDR.BYTE = 0x00;
TPU3.TIOR.BIT.IOA = 0x07;
TPU3.TIOR.BIT.IOB = 0x00;
TPU3.TIER.BIT.TGIEA = 1;
TPU3.TGRA = 8190; //0.0625s delay
TPU3.TCNT = 0;
TPU.TSTR.BIT.CST3 = 1;
}
void TPU3_handler(){
P2.DR.BIT.B7 = 1;
TPU3.TSR.BIT.TGFA = 0;
index ++;
//sendSerial(index);
if(index == 8 - level){
//sendSerial('a');
update_Snake();
//The snake reaches the boundary
if(lineX[head] < 0 || lineX[head] > 15 || lineY[head] < 0 || lineY[head] > 15){
//Stop the timer
TPU.TSTR.BIT.CST3 = 0;
//Update the information on the panel
LCD_SetColor(LCD_StandardColor(15));
LCD_FillRect(0,128,128,32);
LCD_SetColor(LCD_StandardColor(0));
LCD_DrawString("You Lose!",10,133);
LCD_DrawString("Score: ",20,143);
LCD_DrawString("Level: ",20,153);
LCD_DrawInt(score,80,143);
LCD_DrawInt(level,80,153);
}
//The snake meets its body
temp = tail;
while(temp < head){
if(lineX[head] == lineX[temp] && lineY[head] == lineY[temp]){
TPU.TSTR.BIT.CST3 = 0;
//Update the information on the panel
LCD_SetColor(LCD_StandardColor(15));
LCD_FillRect(0,128,128,32);
LCD_SetColor(LCD_StandardColor(0));
LCD_DrawString("You Lose!",10,133);
LCD_DrawString("Score: ",20,143);
LCD_DrawString("Level: ",20,153);
LCD_DrawInt(score,80,143);
LCD_DrawInt(level,80,153);
}
temp ++;
}
if(lineX[head] == foodx && lineY[head] == foody){
meetNut();
}
index = 0;
}
P2.DR.BIT.B7 = 0;
}