Question
I needed help with running a stepper motor using Codewarrior and a Dragon 12 board. I have the keypad code, LCD code, and a main
I needed help with running a stepper motor using Codewarrior and a Dragon 12 board.
I have the keypad code, LCD code, and a main file which you can use to test the other 2 files, but I am struggling on how to write a C code to interact with the stepper motor and implement that into the main file.
[Main.C]
//The project has two device drivers: one for the keypad and other for the LCD
//You need to write your a device driver that will control the stepper motor
#include
#include "derivative.h" /* derivative-specific definitions */
#include"Keypad.h"
#include "LCD.h"
#define EDIT_COL 810
char buf[8];
int bufp;
void just_demo(void);
void delay_ms(unsigned);
void main(void) {
char k;
int i;
Keypad_init();
LCD_init();
LCD_setCursor(0,0);
LCD_print("Enter Pos:");
LCD_setCursor(1,0);
LCD_print("Curr Pos:");
LCD_setCursor(1,EDIT_COL);
LCD_print("Stop."); // assume stopped & at pos = 0
for(;;) {
//read the command position from user...
//first put the cursor there so that we print as user is entering keys...
LCD_setCursor(0,EDIT_COL);
//next: keep reading until user press '#' which is key E in this board
//store in buffer & display on LCD what user is entering
//we will assume correct entry
bufp = 0;
k = Keypad_wait_keypress();
while( k!= 0x0E && bufp < 8 ){
buf[bufp++] = k; // store pressed key in buffer
LCD_putchar(k+'0'); //display as user is entering
Keypad_wait_keyup(); //wait until user release this key
k = Keypad_wait_keypress(); //read next key and back to check...
}
//your code should begin here...
//buf has the commanded position and bufp is their count
//move the stepper to that angle given its current position.....
just_demo();
//The stepper should have reached its commanded pos now....
//display curr pos
LCD_setCursor(1,EDIT_COL);
for(i = 0;i < bufp ; i++)
LCD_putchar(buf[i]+'0');
//erase old commanded pos
LCD_setCursor(0,EDIT_COL);
LCD_print(" ");
}
}
void just_demo(){
int i;
for( i = 0; i < 5 ; i++){
LCD_setCursor(1, EDIT_COL);
LCD_print("Mot...");
delay_ms(500);
LCD_setCursor(1, EDIT_COL);
LCD_print(" ");
delay_ms(500);
}
}
/*----------------------------------
;
; delay for 1 us
*/
void delay_1us(){
asm{
PSHX
LDX #4
L1: DBNE X,L1
PULX
}
}
/*------------------------------------------------
; delay_us
------------------------------------------------*/
void delay_us(unsigned int us ){
asm{
pshd
dd: JSR delay_1us
DBNE D, dd
puld
}
}
/*-------------------
; delay_ms
;----------------------------- */
void delay_ms(unsigned int ms){
asm{
pshd
; 2 clock cycles
PSHX ; 2 clock cycles
OutLoop:
LDX #7993 ; 2
InLoop:
DBNE X, InLoop ; 3/3 ( 3 cycles both ways)
DBNE D, OutLoop ; 3/3
PULX ; 3
puld
}
}
[Keypad.C]
#include "keypad.h" #include
void delay_us(unsigned int); void delay_ms(unsigned int);
// Keypad Device Driver
int col, row;
/*------------------------------------------------------------- ; Keypad_init ; The Keypad on the dragon12 board is connected to port A ; configure port A pins as input & enable the internal pullup registers on them -----------------------------------------------------------------*/
void Keypad_init(){ DDRA = 0; PUCR |= 1 ; //Pull-Up Port A Enable PORTA = 0; //PAx would be driven low once we change its direction in DDRAx to be an output pin }
/*--------------------------------------------------------------------------- ; Keypad_non_scan ; returns the hex code of the currently pressed key, or return $10 if all keys are up ; ; This function does not scan all rows and columns. Instead it accesses the key (if any) in just two quick steps: ; 1. Makes all rows outputs (driven low) and cols as inputs. ; It then reads the cols from PORTA ; 2. It changes the direction of rows as inputs and cols as outputs (driven low). ; It then reads rows from PORTA ; with the row and the col, we do some lookup to find the pressed key or $10
; ----------------------------------------------------------*/ //rows:PORTA[7:4] cols:PORTA[3:0] char Keypad_non_scan(){ extern char keys[][5]; extern char row_col_tab[]; // rows are out, cols are in DDRA = 0xF0; // wait few cycles as noted in the manual delay_us(5); //get col: $xE(leftmost column), $xD, $xB, $x7, or $xF if no press col = PORTA & 0x0F; //rows are ins, cols are outs DDRA = 0x0F; //wait few cycles as noted in the manual delay_us(5); //get row: $Ex (first row), $Dx, $Bx, $7x, or $Fx if no press row = (PORTA >> 4) &0x0F; //map them into values between 0 & 4 row = row_col_tab[row]; // now could be any value from 0 through 4 col = row_col_tab[col]; // so does col return keys[row][col]; }
/*------------------------------------------------------------------------------------------ ; Keypad_read; ; This is a debounced function ; It keeps sampling the keypad every 5ms until the three samples are same ; ; return the pressed hex key, or $10 if all keys are up (debounced) -------------------------------------------------*/ char Keypad_read(){ char k[3]; do{ //first sample k[0]=Keypad_non_scan(); delay_ms(5); //2nd sample k[1]=Keypad_non_scan(); delay_ms(5); //third sample k[2]=Keypad_non_scan(); }while(k[0] != k[1] || k[1]!=k[2]); // keep sampling until the 3 samples are same //either the pressed key or 0x10 (debounced) return k[0]; }
/*---------------------------------------------------- ; Keypad_wait_keypress: ; wait until a key is pressed and return --------------------------------------------------*/ char Keypad_wait_keypress(){ char key; for( key = Keypad_read() ; key ==0x10; key = Keypad_read() ) //keep trying until a key is pressed ; return key; }
/*-------------------------------------------------- ; Keypad_wait_keyup: ; wait until all keys are up and then return -------------------------------------------------------*/
void Keypad_wait_keyup(){ while( Keypad_read() != 0x10 ) //keep trying until all keys are up ; }
//--------------------------------------- // lookup the key by row & col //col 0 1 2 3 4 // PA0 PA1 PA2 PA3 // // row char keys[][5]={ {0x01, 0x02, 0x03, 0x0A ,0x10}, // 0 PA4 {0x04, 0x05, 0x06, 0x0B ,0x10}, // 1 PA5 {0x07, 0x08, 0x09, 0x0C ,0x10}, // 2 PA6 {0x0F, 0x00, 0x0E, 0x0D ,0x10}, // 3 PA7 {0x10, 0x10, 0x10, 0x10, 0x10} // 4 };
/*---------------------------------------------------------- ; lookup the row or the col by the value that is read from PORTA during Keypad_non_scan ; ; when a key is detected, the 4-bit value read from PORTA could be 7, B, D, E. Otherwise, it is F ; We map the detected 4-bit value into row or col:0-3. F will be mapped into 4 */ char row_col_tab[]={ 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 2, 4, 1, 0, 4 // 0 1 2 3 4 5 6 7 8 9 A B C D E F };
[LCD.C]
#include
#include "LCD.h"
void delay_ms(unsigned), delay_us(unsigned);
#define E 2 #define RS 1
void lcd_send_nibble(char c); void lcd_send_data(unsigned char data); void lcd_send_cmd(unsigned char cmd);
/*---------------------------------------------------------- ; LCD connections to MCU ; LCD MC9S12DG256x ; === ============ ; RS <----> PK0 RS = 0 for lcd commands transfer, RS=1 for lcd data transfer ; ; E <----> PK1 a high plus must be generated on E when writing to LCD ; ; D4 <----> PK2 ; D5 <----> PK3 ; D6 <----> PK4 ; D7 <----> PK5 ; R/W pin on LCD is connected to ground in this board (Write Only connection)
*/
//; initalize the LCD // check HD44780 datasheet void LCD_init(){ delay_ms(15); //wait 15ms (datasheet) DDRK = 0xFF; // config port K as an output port. //send 3 as a nibble first time (datasheet) lcd_send_nibble(3); delay_us(4100); //wait 4.1 ms (datasheet) //send 3 as a nibble second time (datasheet) lcd_send_nibble(3); delay_us(100); //wait 100us (datasheet) //send 3 as a nibble 3rd time (datasheet) lcd_send_nibble(3); //send 2 as a nibble 4th time (datasheet) lcd_send_nibble(2); //start configuration now // function set: 0 0 1 DL N F x x // ;(DL= 0 for 4 bit mode, N=1 for 2lines, F=0 for 5x7) lcd_send_cmd(0x28); // LCD is connected as 4-bit mode interface to port K // display Off: 0 0 0 0 1 D C B // D = 0 C =0 B = 0 lcd_send_cmd(0x08); LCD_clear(); //display On: 0 0 0 0 1 D C B //D = 1 C =0 B = 0 //display on, cursor off, no blinking lcd_send_cmd(0x0C); //entry mode: 0 0 0 0 0 1 I/D S // I/D = 1 cursor increment, S = 0 to disable display shift lcd_send_cmd(0x06); }
//send lower nibble [3:0] out to LCD void lcd_send_nibble(char c){ c &= 0x0F; c <<= 2; // adjust for portk[5:2] //drive port K pins and generate a 1us pulse on E PORTK = c; //E = 0, RS = 0 PORTK[5:2] = data[5:2] PORTK |= E; //E = 1 , RS =0 PORTK &= ~E; //E = 0 , RS =0 delay_us(40); //wait 40us (datasheet) }
// send 8-bit command to LCD void lcd_send_cmd(unsigned char cmd){ char save = cmd; //send upper nibble first cmd &= 0xF0; cmd >>= 2; // adjust for portk [5:2] PORTK = cmd; // E = 0, RS = 0 PORTK[5:2] = data[5:2] //generate a pulse on E PORTK |=E; // E = 1 , RS =0 PORTK &=~E; // E = 0 , RS =0 delay_us(40); //send lower nibble next cmd = save; cmd &= 0x0F; cmd <<= 2; // adjust for portk[5:2] PORTK = cmd; // E = 0, RS = 0 PORTK[5:2] = data[5:2] //generate a pulse on E PORTK |=E; // E = 1 , RS =0 PORTK &=~E; // E = 0 , RS =0 delay_us(40); }
// send 8-bit data to LCD // same as lcd_send_cmd except RS must be 1
void lcd_send_data(unsigned char data){ char save = data; //send upper nibble first data &=0xF0; data >>= 2; data |= RS; PORTK = data; // E = 0 , RS = 1 PORTK[5:2] = data[5:2] //generate a pulse on E PORTK |=E; // E = 1 , RS =1 PORTK &=~E; // E = 0 , RS =1 delay_us(40); //send lower nibble next data = save; data &=0x0F; data <<= 2; data |= RS; PORTK = data; // E = 0 , RS = 1 PORTK[5:2] = data[5:2] //generate a pulse on E PORTK |=E; // E = 1 , RS =1 PORTK &=~E; // E = 0 , RS =1 delay_us(40); } //put the cursor at row and col. LCD with 2x16 //row: 0 or 1 //col: 0 through 15 void LCD_setCursor(int row, int col){ static char A[]={0,0x40}; row &=1; col &=0x0F; lcd_send_cmd((A[row]|0x80) + col); }
//Clear the LCD and send cursor home void LCD_clear(){ //$01 Clear command (datasheet) lcd_send_cmd(0x01); //wait 1.6ms (datasheet) delay_us(1600); //$02 Cursor Home command (datasheet) lcd_send_cmd(0x02); //wait 1.6ms (datasheet) delay_us(1600); }
// print a character on LCD at the current cursor pos void LCD_putchar(char ch){ lcd_send_data(ch); } //print a string on LCD void LCD_print(char *s){ while(*s) LCD_putchar(*s++); }
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started