我使用的是MSP-EXP430G2板与MSP430G2231单片机,我想让我的代码在按钮被按下时切换字符串。这是连接到 BIT3
.
它连接到一个像这样的LCD。
Connections
P1.0 - D4 Pin11
P1.1 - D5 Pin12
P1.2 - D6 Pin13
P1.3 - D7 Pin14
P1.4 - RS Pin4
P1.5 - R/W Pin5
P1.6 - E Pin6
#define DR P1OUT = P1OUT | BIT4 // define RS high
#define CWR P1OUT = P1OUT & (~BIT4) // define RS low
#define READ P1OUT = P1OUT | BIT5 // define Read signal R/W = 1 for reading
#define WRITE P1OUT = P1OUT & (~BIT5) // define Write signal R/W = 0 for writing
#define ENABLE_HIGH P1OUT = P1OUT | BIT6 // define Enable high signal
#define ENABLE_LOW P1OUT = P1OUT & (~BIT6) // define Enable Low signal
void set_input(void) {
const unsigned char z = 0;
switch (clock_input) {
default:
clock_input = 0;
case 0:
lcd_init();
send_string("Frequency is");
send_command(0xC0);
break;
case 1:
lcd_init();
send_string("Period is");
send_command(0xC0);
break;
}
}
void main(void) {
WDTCTL = WDTPW + WDTHOLD; // stop watchdog timer
DCOCTL = 0;
BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation
if (!(P1IN & BIT3)) { // Check if pushbutton down
++clock_input; // Switch clock input
set_input(); //
}
}
我是这样做的,这是我发送字符串的方式。
void send_string(char *s) {
while (*s) {
send_data(*s);
s++;
}
}
void send_command(unsigned char cmd) {
check_busy();
WRITE;
CWR;
P1OUT = (P1OUT & 0xF0) | ((cmd >> 4) & 0x0F); // send higher nibble
data_write(); // give enable trigger
P1OUT = (P1OUT & 0xF0) | (cmd & 0x0F); // send lower nibble
data_write(); // give enable trigger
}
void lcd_init(void) {
P1DIR |= 0xFF;
P1OUT &= 0x00;
send_command(0x33);
send_command(0x32);
send_command(0x28); // 4 bit mode
send_command(0x0E); // clear screen
send_command(0x01); // cursor position
send_command(0x06); // increment cursor
send_command(0x80);
}
问题是,当我把代码放在... ... main
然后按下按钮,什么也没发生。当我把它放在一个循环中时,它只是向前和向后切换。我不知道板子上的1.3(S2)引脚是否干扰了按钮,因为它们有相同的名字(P1.3)。
如果我们看一下你的代码,就会发现一些很重要的东西。
void main(void) {
// just statements
if (!(P1IN & BIT3)) {
// just statements
}
}
你的代码没有循环 如果你让你的 main
函数end是单片机按照你的要求停止执行代码。因此,你会在每个单片机项目的main结尾处发现以下内容。
while(1){
}
这样应用程序就会一直运行下去 如果你想让一些事情一直到时间(或电源)结束,你必须在while循环的主体中加入你的代码。
if (!(P1IN & BIT3)) {
这段代码很好,可以加到while循环的主体中,但是要注意,while循环是以你的CPU的速度减去执行循环主体的时间来循环的。因此,它读取的值是 P1IN
太多了,无法真正感知。因此,你需要一个名为 delay
. 这让CPU忙于输入的时间,这样我们就可以读取输入引脚,并对其做出反应,而不会直接覆盖我们已经做的事情。
这是一个足够好的版本 delay
暂时如此。
void ms_delay(long milliseconds)
{
int n;
while(milliseconds--)
{
for (n=0 ; n<200 ; ++n);
}
}
但在我们实际读取东西之前,我们需要配置端口。这可以通过 DIR
注册。由于你已经将按钮连接到 P1
我们将配置 P1DIR
. P1DIR &= ~BIT3
(设置 P1Dir
在第3位上调为0,其余部分不动)
现在我们可以改为 P1IN
并在 BIT3
.
void ms_delay(long milliseconds)
{
int n;
while(milliseconds--)
{
for (n=0 ; n<16000 ; ++n) {} // please note that the 16000 value is very approximate and might need to be tweaked.
}
}
void main(){
// initialization of your hardware
WDTCTL = WDTPW + WDTHOLD;
P1DIR &= ~BIT3; // set bit 3 to 0 (INPUT) and leave the rest. (P1DIR = P1DIR & 11111011)
while(1){
ms_delay(100); // wait a 100 milliseconds
if( P1IN & BIT3 == 1){
// hurray the button is pressed. (if your button is connected to VCC at least.
}
}
}
上面这段代码应该可以用。但如果你不想让这些 LED1
或 LED2
你需要添加 P1DIR |= BIT0
的初始化代码,并将循环的主体改为。
ms_delay(100); // wait a 100 milliseconds
if( P1IN & BIT3 == 1){
P1OUT |= BIT0;
}
else{
P1OUT &= ~BIT0;
}
至于你说的引脚冲突问题 看来你有一个问题。P1DIR |= 0xFF;
是配置了 P1
端口作为输出,但你想用 P1.3
作为输入,这样就不能一起使用了。
请大家放心地去找关于真正的教程。微控制器. 如果你真的想知道的事情,关于微控制器,访问制造商的网站。这是 MSP 在这种情况下,他们有几个文件来帮助你。只要搜索一下单片机的零件号,大部分时间都能找到。重要的文件有
你提供的代码不完整,因为变量 clock_input
甚至没有在任何地方声明。