Stackoverflow,你以前帮助过我,我想我再次需要你的帮助。我正在尝试使用 PIC18F2550 上的 GPIO 对我自己的串行进行 bit-bang。这连接到一些移位寄存器 (3x74LS595),其中最后一个连接到标准 HD44780 LCD。到目前为止,我的时钟和闩锁工作正常,经过长时间的战斗,数据现在也被正确吐出(结果桶移位效果不佳,事情会很乐意吐出数据超出范围但我离题了)。
我的问题是,要使用 LCD,我需要将启用引脚切换为数据时钟,因此为了保存代码,我只需嵌套另一个循环,该循环运行两次并切换启用标志,否则会吐出相同的字节。从理论上讲,这应该是从 12 到 24 吐出的字节数的两倍。无论出于何种原因,添加此循环时它都不起作用。它只是吐出两个字节并退出。没有它,它会吐出所有 12 个字节(尽管 LCD 设置不正确,因为启用不存在)。
这是它工作的图片,没有嵌套的启用循环:
D0 是数据,下面的 D1/2 分别是时钟/负载。
这里是 for 循环:
最左边的那个边缘是线的初始重置。我知道它在这两个字节之后完成,因为它会发出我拥有的小蜂鸣器的哔哔声,表明所有有意义的代码都已完成。
这是一个代码转储:
//First testing program for PIC18F2550
#include <p18f2550.h>
#include <stdlib.h>
#include <delays.h>
#define _XTAL_FREQ 4915200
#pragma config PLLDIV = 1
#pragma config CPUDIV = OSC1_PLL2
#pragma config FOSC = XT_XT
#pragma config MCLRE = ON
#pragma config BOR = OFF
#pragma config WDT = OFF
#pragma config IESO = OFF
#pragma config PBADEN = OFF
#pragma config LVP = OFF
unsigned char setupstream[12] = {0b0011, 0b0011, 0b0011, 0b0010, 0b0010, 0b1000, 0b0000, 0b0001, 0b0000, 0b1111, 0b0000, 0b0110};
unsigned char teststream[6] = {0xF0, 0x00, 0xFF, 0x00, 0xFF, 0x00};
unsigned char letterstream[2] = {0b0010, 0b0001};
unsigned char c1 = 0, c2 = 0, c3 = 0, outreg = 0, outmask = 0, feedout = 0;
void main(void){
//CONFIG4L = 0b01000001;
UCONbits.USBEN=0;
UCFGbits.UTRDIS=1;
//OSCCONbits.IRCF2=1;
//OSCCONbits.IRCF1=1;
//OSCCONbits.IRCF0=1;
OSCCONbits.SCS1 = 0;
OSCCONbits.SCS0 = 0;
BAUDCONbits.TXCKP=0;
SPBRG = 0x3F; //1200 baud
TRISA = 0x00;
TRISB = 0xFF;
TRISC = 0x00;
LATCbits.LATC0 = 1; //Start: beep the speaker
Delay10KTCYx(8);
LATCbits.LATC0 = 0;
Delay10KTCYx(8);
LATA = 0; //reset
Delay10KTCYx(8);
LATAbits.LATA2 = 1; //load the reset
Delay10KTCYx(8);
LATAbits.LATA3 = 1; //stop reset
LATAbits.LATA2 = 0;
Delay10KTCYx(123);
for(c1==0; c1<12; c1++){
for(c2==0; c2<2; c2++){
outreg = setupstream[c1] << 2; //nibble of data needs to be in the middle
//outreg |= 0b00000010; //set flags
//outreg ^= 0b00000001;
outmask = 0x80;
for(c3=0; c3<8; c3++){
LATAbits.LATA0 = (outreg & outmask) ? 1:0;
outmask >>=1;
Delay10KTCYx(8);
LATAbits.LATA1 = 1; //clock the data out
Delay10KTCYx(8);
LATAbits.LATA1 = 0;
}
Delay10KTCYx(8);
LATAbits.LATA2 = 1; //one byte fed out; load it into shift regs
Delay10KTCYx(8);
LATAbits.LATA2 = 0;
}
}
LATAbits.LATA0 = 0; //Done, clear the line and
LATCbits.LATC0 = 1; //Beep the speaker
Delay10KTCYx(8);
LATCbits.LATC0 = 0;
Delay10KTCYx(8);
while(1){ //Idle
}
}
在上面的代码中,我什至禁用了切换以查看它是否会吐出所有字节。可能不会。我正在认真考虑只在汇编中完成这一切,因为对于 C 语言,我在看似简单的东西上遇到了很多问题。感觉就像我无法控制这件事的背景中发生的事情。我正在使用 Pickit 3,但如果我想了解实际情况,我可能只需要挖掘 ICD2。