我是新手对这个板子不怎么熟悉,想请教一下。就觉得很奇怪为什么LCD(8位,16*2,HD44780)只能亮不能显示文字,因为我在LCD控制函数后面设置断点,并通过watch window观察了8位GPIO口的数据了,是跟我想输入的函数相符合的,另外也通过E置1再置0输出给LCD了,为什么还是不行。另外还有点很奇怪的是我的函数包含了一个系统延迟,如果不设置断点run了以后再reset是回到start up文件中的system_initial函数,并且怎么也跳不出来。如果把系统延迟换成麻瓜while延迟就不会卡在循环里,这是什么情况。。 后面附带我写的程序和问题截图,也是非常的菜。一开始我们组搞硬件的根据网上资料连的数据线,分散得乱七八糟,我lcd_write程序也是写得非常奇葩,但是debugger模式下观察gpio的结果还是对的。我同学说我没设置地址线,我也搞不清,需要地址线吗?不是直接把data传给lcd就行了嘛= =求指导,这个程序已经搞了2天了还没有头绪。。
#include <MKL25Z4.h>
// Program ID
uint8_t program_author[] = "Donald Weiman";
uint8_t program_version[] = "LCD-AVR-8d-s (gcc)";
uint8_t program_date[] = "Sep 16, 2013";
// Function Prototypes
void lcd_write_8(uint8_t);
void lcd_write_instruction_8d(uint8_t);
void lcd_write_character_8d(uint8_t);
void lcd_write_string_8d(uint8_t *);
void lcd_init_8d(void);
//system delay
volatile uint32_t msTicks;
void SysTick_Handler(void) {
msTicks++; /* increment counter necessary in Delay() */
}
__INLINE static void Delay (uint32_t dlyTicks) {
uint32_t curTicks;
curTicks = msTicks;
while ((msTicks - curTicks) < dlyTicks);
}
//simple delay
//void Delay(int a){
// int i;
// for(i=0;i<a*100;i++);
//}
/******************************* Main Program Code *************************/
int main(void)
{
SystemCoreClockUpdate();
// initialize the LCD controller as determined by the defines (LCD instructions)
lcd_init_8d(); // initialize the LCD display for an 8-bit interface
SysTick_Config(10000);
// display the first line of information
lcd_write_string_8d(program_author);
// set cursor to start of second line
lcd_write_instruction_8d(0xC0);
Delay(0x1); // 40 uS delay (min)
// display the second line of information
lcd_write_string_8d(program_version);
// endless loop
while(1);
// return 0;
}
/******************************* End of Main Program Code ******************/
/*============================== 8-bit LCD Functions ======================*/
/*
Name: lcd_init_8d
Purpose: initialize the LCD module for a 8-bit data interface
Entry: equates (LCD instructions) set up for the desired operation
Exit: no parameters
Notes: uses time delays rather than checking the busy flag
*/
void lcd_init_8d(void)
{
SIM->SCGC5|=(1<<9)|(1<<10)|(1<<12);
PORTA->PCR[1]=(1<<8);
PORTA->PCR[2]=(1<<8);
PORTD->PCR[4]=(1<<8);
PORTA->PCR[12]=(1<<8);
PORTB->PCR[0]=(1<<8);
PORTB->PCR[1]=(1<<8);
PORTB->PCR[2]=(1<<8);
PORTB->PCR[3]=(1<<8);
// Power-up delay
Delay(0x100); // initial 40 mSec delay
// configure the microprocessor pins for the data lines
PTA->PDDR=(1<<1)|(1<<2)|(1<<12); // all 8 data lines - output
PTB->PDDR=(1<<0)|(1<<1)|(1<<2)|(1<<3);
PTD->PDDR=(1<<4);
// configure the microprocessor pins for the control lines
PTD->PDDR|=(1<<0); // E line - output
PTA->PDDR|=(1<<13); // RS line - output
// Reset the LCD controller
PTD->PCOR=(1<<5); // R/W=0 PCOR doesn't change
lcd_write_instruction_8d(0x38); // 0011 1000=fucntion set
Delay(0x100); // 4.1 mS delay (min)
lcd_write_instruction_8d(0x01); //0000 0001=clear display
Delay(0x100); // 40 uS delay (min)
// Display On/Off Control instruction
lcd_write_instruction_8d(0x0E); // 0000 1110=turn the display ON
Delay(0x100); // 40 uS delay (min)
lcd_write_instruction_8d(0x06); // 0000 0110=entry mode set
}
/*...........................................................................
Name: lcd_write_string_8d
; Purpose: display a string of characters on the LCD
Entry: (theString) is the string to be displayed
Exit: no parameters
Notes: uses time delays rather than checking the busy flag
*/
void lcd_write_string_8d(uint8_t theString[])
{
volatile int i = 0; // character counter*/
while (theString[i] != 0)
{
lcd_write_character_8d(theString[i]);
i++;
Delay(0x100); // 40 uS delay (min)
}
}
/*...........................................................................
Name: lcd_write_character_8d
Purpose: send a byte of information to the LCD data register
Entry: (theData) is the information to be sent to the data register
Exit: no parameters
Notes: does not deal with RW (busy flag is not implemented)
*/
void lcd_write_character_8d(uint8_t theData)
{
PTA->PSOR=(1<<13); // select the Data Register (RS high)
PTD->PCOR=(1<<0); // make sure E is initially low
lcd_write_8(theData); // write the data
}
/*...........................................................................
Name: lcd_write_instruction_8d
Purpose: send a byte of information to the LCD instruction register
Entry: (theInstruction) is the information to be sent to the instruction register
Exit: no parameters
Notes: does not deal with RW (busy flag is not implemented)
*/
void lcd_write_instruction_8d(uint8_t theInstruction)
{
PTA->PCOR=(1<<13); // select the Instruction Register (RS low)
PTD->PCOR=(1<<0); // make sure E is initially low
lcd_write_8(theInstruction); // write the instruction
}
/*...........................................................................
Name: lcd_write_8
Purpose: send a byte of information to the LCD module
Entry: (theByte) is the information to be sent to the desired LCD register
RS is configured for the desired LCD register
E is low
RW is low
Exit: no parameters
Notes: use either time delays or the busy flag
*/
void lcd_write_8(uint8_t theByte)
{
// 'Address set-up time' (40 nS)
uint8_t a;
int i;
PTA->PDOR=(0<<1)|(0<<2)|(0<<12); // all 8 data lines - output
PTB->PDOR=(0<<0)|(0<<1)|(0<<2)|(0<<3);
PTD->PDOR=(0<<4);
for(i=0;i<8;i++){
a=theByte>>i;
a=a&(0x01);
switch(i){
case 0:
if(a==0x01){
PTA->PDOR|=(1<<1);
}
break;
case 1:
if(a==0x01){
PTA->PDOR|=(1<<2);
}
break;
case 2:
if(a==0x01){
PTD->PDOR|=(1<<4);
}
break;
case 3:
if(a==0x01){
PTA->PDOR|=(1<<12);
}
break;
case 4:
if(a==0x01){
PTB->PDOR|=(1<<0);
}
break;
case 5:
if(a==0x01){
PTB->PDOR|=(1<<1);
}
break;
case 6:
if(a==0x01){
PTB->PDOR|=(1<<2);
}
break;
case 7:
if(a==0x01){
PTB->PDOR|=(1<<3);
}
break;
}
a=theByte;
}
// put information on data lines
PTD->PSOR=(1); // Enable pin high
Delay(0x100); // implement 'Data set-up time' (80 nS) and 'Enable pulse width' (230 nS)
PTD->PCOR=(1); // Enable pin low
Delay(0x100); // implement 'Data hold time' (10 nS) and 'Enable cycle time' (500 nS)
}
一旦使用系统延迟就卡BX在这里,很怪,单步执行挑不出来,暂停也跳不出来
|