This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

求助

Other Parts Discussed in Thread: MSP430G2553, MSP430G2253

这个程序为什么按下按键p1.3无中断响应?这是由产生pwm波的程序和ad采样显示(lcd1602)合成的,在产生pwm波的程序里p1.3可以响应。

#include "msp430g2553.h"
#include "lcd1602.c"

#define uchar unsigned char
#define uint unsigned int
uint a[11]={0},num; //定义数组用于储存采样值
uint shi=0,shifen=0,gewei=0,baifen=0,baifen1=0,shi1=0,shifen1=0,gewei1=0;
long P10=0,P11=0,P10_V=0,P11_V=0,A=0,A1=0; //定义变量
uchar table[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; //0~9

void ADC10_init(); //声明ADC10初始化函数
void display(); //显示函数
void pwm();
void main()
{ WDTCTL = WDTPW + WDTHOLD; //关狗
LCD_init_first();
LCD_init();
ADC10_init(); //初始化ADC10
while(1)
{
pwm();
ADC10CTL0 &=~ ENC; //禁用ADC10的Conversion
while(ADC10CTL1 & ADC10BUSY); //测忙
ADC10SA= (unsigned int)a; //获取a[]的首地址
ADC10CTL0 |= ADC10SC + ENC; //启动ADC10
_BIS_SR(LPM0_bits+GIE); //低功耗模式0,开中断

P10=a[1]+a[3]+a[5]+a[7]; //将A0采样值相加
P10= P10/4.0; //求平均值
P10_V = P10*250/1023; //转化为电压并乘以100
display(); //显示

}
}
void display()
{ uint P10_int;
P10_int=(uint)P10_V;

/*求A0采样的各个位*/
A=-14*P10_int+1733.3;
shi = A/1000; //求个位
gewei =(A%1000)/100; //求十分位
shifen =((A%1000)%100)/10; //求百分位
baifen =((A%1000)%100)%10;

/*显示A0处的值*/
LCD_write_command(0x80);
LCD_write_data(table[shi]);
LCD_write_data(table[gewei]);
LCD_write_data('.');
LCD_write_data(table[shifen]);
LCD_write_data(table[baifen]);
LCD_write_data('V');
}

void ADC10_init()
{
/* ADC中断使能+打开ADC10+打开基准生成电压+采样保持时间16*ADC10CLK+(VREF+ and VR-=AVS)+ADC10 multi+2.5V */
ADC10CTL0 = ADC10IE + ADC10ON + REFON + ADC10SHT_2 + SREF_1 + MSC + REF2_5V;
/* 重复序列转换+时钟源选择ADC10OSC+0分频+选择channel1 */
ADC10CTL1 = CONSEQ_3 + + ADC10DIV_0 + INCH_1;
ADC10AE0 |=BIT0+BIT1+BIT3; //打开模拟输入通道
ADC10DTC1 |= 0X08; //采样数为8
}
void pwm()
{
P1SEL |= BIT2;
P1DIR |= BIT2; // P1.2 as TA0.1 output
P1REN |= BIT3;
P1IES |= BIT3; //P1.3 high to low interrupt
_EINT();
P1IFG = 0;
P1IE |= BIT3; //Enable P1.3 interrupt

CCTL1 = OUTMOD_3; /* PWM output mode: 3 - PWM set/reset */

CCR0 = 195;

CCR1 = 15;

TACTL = TASSEL_2 + TACLR + MC_1; // SMCLK, UP mode.
__low_power_mode_0();
}

/*#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void)
{
__bic_SR_register_on_exit(CPUOFF); //唤醒CPU
}*/
#pragma vector = PORT1_VECTOR
__interrupt void port1_isr(void)
{
if (P1IFG & BIT3)
{
for(int i=0; i<10; i++);
CCR1 += 15;
if (CCR1 > 195)
CCR1 = 0;
P1IFG &= ~BIT3;
}
}

这是lcd1602的程序






#include <intrinsics.h>
#include <msp430g2253.h>
#include <msp430.h>
/*****************************************************
端口定义
****************************************************/
#define LCD_EN_PORT P1OUT //以下2个要设为同一个口
#define LCD_EN_DDR P1DIR
#define LCD_RS_PORT P1OUT //以下2个要设为同一个口
#define LCD_RS_DDR P1DIR
#define LCD_DATA_PORT P2OUT //以下3个要设为同一个口
#define LCD_DATA_DDR P2DIR //一定要用高4位
#define LCD_RS BIT6
#define LCD_EN BIT7
#define LCD_DATA BIT7|BIT6|BIT5|BIT4 //4位数据线连接模式
/***************************************************
预定义函数
**************************************************/
void LCD_init(void);
void LCD_init_first(void);
void LCD_en_write1(void); //上升沿使能
void LCD_en_write2(void); //下降沿使能
void LCD_write_command(unsigned char command);
void LCD_write_data(unsigned char data);
void LCD_set_xy (unsigned char x, unsigned char y);
void LCD_write_string(unsigned char X,unsigned char Y, unsigned char *s);
void LCD_write_char(unsigned char X,unsigned char Y, unsigned char data);
void delay_1ms(void);
void delay_nus(unsigned int n);
void delay_nms(unsigned int n);
/********************************************
LCD液晶操作函数
*******************************************/
void LCD_init_first(void) //LCD1602液晶初始化函数(热启动)
{
delay_nms(500);
LCD_DATA_DDR|=LCD_DATA; //数据口方向为输出
LCD_EN_DDR|=LCD_EN; //设置EN方向为输出
LCD_RS_DDR|=LCD_RS; //设置RS方向为输出
delay_nms(50);
LCD_write_command(0x30);
delay_nms(50);
LCD_write_command(0x30);
delay_nms(5);
LCD_write_command(0x30);
delay_nms(500);
}
/*****************************************
*
* LCD1602液晶初始化函数
*
****************************************/
void LCD_init(void)
{
delay_nms(500);
LCD_DATA_DDR|=LCD_DATA; //数据口方向为输出
LCD_EN_DDR|=LCD_EN; //设置EN方向为输出
LCD_RS_DDR|=LCD_RS; //设置RS方向为输出
delay_nms(500);
LCD_write_command(0x28); //4位数据接口
delay_nms(50);
LCD_write_command(0x28); //4位数据接口
delay_nms(50);
LCD_write_command(0x28); //4位数据接口
delay_nms(50);
LCD_en_write2();
delay_nms(50);
LCD_write_command(0x28); //4位数据接口
delay_nms(500);
LCD_write_command(0x01); //清屏
LCD_write_command(0x0c); //显示开,关光标,不闪烁
LCD_write_command(0x06); //设定输入方式,增量不移位
delay_nms(50);
}
/*****************************************
*
* 液晶使能上升沿
*
****************************************/
void LCD_en_write1(void)
{
LCD_EN_PORT&=~LCD_EN;
delay_nus(10);
LCD_EN_PORT|=LCD_EN;
}
/*****************************************
*
* 液晶使能下降沿
*
****************************************/
void LCD_en_write2(void)
{
LCD_EN_PORT|=LCD_EN;
delay_nus(10);
LCD_EN_PORT&=~LCD_EN;
}
/*****************************************
*
* 写指令函数
*
****************************************/
void LCD_write_command(unsigned char command)
{
delay_nus(16);
P2SEL=0x00;
LCD_RS_PORT&=~LCD_RS; //RS=0
LCD_en_write1();
LCD_DATA_PORT&=0X0f; //清高四位
LCD_DATA_PORT|=command&0xf0; //写高四位
delay_nus(16);
LCD_en_write2();
command=command<<4; //低四位移到高四位
LCD_en_write1();
LCD_DATA_PORT&=0x0f; //清高四位
LCD_DATA_PORT|=command&0xf0; //写低四位
LCD_en_write2();
}
/*****************************************
*
* 写数据函数
*
****************************************/
void LCD_write_data(unsigned char data)
{
delay_nus(16);
P2SEL=0x00;
LCD_RS_PORT|=LCD_RS; //RS=1
LCD_en_write1(); //E上升沿
LCD_DATA_PORT&=0X0f; //清高四位
LCD_DATA_PORT|=data&0xf0; //写高四位
delay_nus(16);
LCD_en_write2();
data=data<<4; //低四位移到高四位
LCD_en_write1();
LCD_DATA_PORT&=0X0f; //清高四位
LCD_DATA_PORT|=data&0xf0; //写低四位
LCD_en_write2();
}
/*****************************************
*
* 写地址函数
*
****************************************/
void LCD_set_xy( unsigned char x, unsigned char y )
{
unsigned char address;
if (y == 0) address = 0x80 + x;
else address = 0xc0 + x;
LCD_write_command( address);
}
/*****************************************
*
*LCD在任意位置写字符串,列x=0~15,行y=0,1
*
****************************************/
void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s)
{
LCD_set_xy( X, Y ); //写地址
while (*s) //写显示字符
{
LCD_write_data( *s );
s++;
}
}
/*****************************************
*
* LCD在任意位置写字符,列x=0~15,行y=0,1
*
****************************************/
void LCD_write_char(unsigned char X,unsigned char Y,unsigned char data)
{
LCD_set_xy( X, Y ); //写地址
LCD_write_data( data);
}
/*****************************************
*
* 1us延时函数
*
****************************************/
void delay_1us(void)
{
asm("nop");
}
/*****************************************
*
* N us延时函数
*
****************************************/
void delay_nus(unsigned int n)
{
unsigned int i;
for (i=0;i<n;i++)
delay_1us();
}
/*****************************************
*
* 1ms延时函数
*
****************************************/
void delay_1ms(void)
{
unsigned int i;
for (i=0;i<1140;i++);
}
/*****************************************
*
* N ms延时函数
*
****************************************/
void delay_nms(unsigned int n)
{
unsigned int i=0;
for (i=0;i<n;i++)
delay_1ms();
}


  • tianxiong Zhang 说:

    这个程序为什么按下按键p1.3无中断响应?这是由产生pwm波的程序和ad采样显示(lcd1602)合成的,在产生pwm波的程序里p1.3可以响应。

    #include "msp430g2553.h"
    #include "lcd1602.c"

    #define uchar unsigned char
    #define uint unsigned int
    uint a[11]={0},num; //定义数组用于储存采样值
    uint shi=0,shifen=0,gewei=0,baifen=0,baifen1=0,shi1=0,shifen1=0,gewei1=0;
    long P10=0,P11=0,P10_V=0,P11_V=0,A=0,A1=0; //定义变量
    uchar table[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; //0~9

    void ADC10_init(); //声明ADC10初始化函数
    void display(); //显示函数
    void pwm();
    void main()
    { WDTCTL = WDTPW + WDTHOLD; //关狗
    LCD_init_first();
    LCD_init();
    ADC10_init(); //初始化ADC10
    while(1)
    {
    pwm();
    ADC10CTL0 &=~ ENC; //禁用ADC10的Conversion
    while(ADC10CTL1 & ADC10BUSY); //测忙
    ADC10SA= (unsigned int)a; //获取a[]的首地址
    ADC10CTL0 |= ADC10SC + ENC; //启动ADC10
    _BIS_SR(LPM0_bits+GIE); //低功耗模式0,开中断

    P10=a[1]+a[3]+a[5]+a[7]; //将A0采样值相加
    P10= P10/4.0; //求平均值
    P10_V = P10*250/1023; //转化为电压并乘以100
    display(); //显示

    }
    }
    void display()
    { uint P10_int;
    P10_int=(uint)P10_V;

    /*求A0采样的各个位*/
    A=-14*P10_int+1733.3;
    shi = A/1000; //求个位
    gewei =(A%1000)/100; //求十分位
    shifen =((A%1000)%100)/10; //求百分位
    baifen =((A%1000)%100)%10;

    /*显示A0处的值*/
    LCD_write_command(0x80);
    LCD_write_data(table[shi]);
    LCD_write_data(table[gewei]);
    LCD_write_data('.');
    LCD_write_data(table[shifen]);
    LCD_write_data(table[baifen]);
    LCD_write_data('V');
    }

    void ADC10_init()
    {
    /* ADC中断使能+打开ADC10+打开基准生成电压+采样保持时间16*ADC10CLK+(VREF+ and VR-=AVS)+ADC10 multi+2.5V */
    ADC10CTL0 = ADC10IE + ADC10ON + REFON + ADC10SHT_2 + SREF_1 + MSC + REF2_5V;
    /* 重复序列转换+时钟源选择ADC10OSC+0分频+选择channel1 */
    ADC10CTL1 = CONSEQ_3 + + ADC10DIV_0 + INCH_1;
    ADC10AE0 |=BIT0+BIT1+BIT3; //打开模拟输入通道
    ADC10DTC1 |= 0X08; //采样数为8
    }
    void pwm()
    {
    P1SEL |= BIT2;
    P1DIR |= BIT2; // P1.2 as TA0.1 output
    P1REN |= BIT3;
    P1IES |= BIT3; //P1.3 high to low interrupt
    _EINT();
    P1IFG = 0;
    P1IE |= BIT3; //Enable P1.3 interrupt

    //参见下面完整配置代码 你再试试 你这里没讲P1.3配置输入模式。

    P1DIR &= ~BIT3; // P1.3 INPUT
    P1REN |= BIT3; // P1.3 pullup
    P1IE |= BIT3; // P1.3 interrupt enabled
    P1IES |= BIT3; // P1.3 Hi/lo edge
    P1IFG &= ~BIT3; // P1.3 IFG cleared



    CCTL1 = OUTMOD_3; /* PWM output mode: 3 - PWM set/reset */

    CCR0 = 195;

    CCR1 = 15;

    TACTL = TASSEL_2 + TACLR + MC_1; // SMCLK, UP mode.
    __low_power_mode_0();
    }

    /*#pragma vector=ADC10_VECTOR
    __interrupt void ADC10_ISR(void)
    {
    __bic_SR_register_on_exit(CPUOFF); //唤醒CPU
    }*/
    #pragma vector = PORT1_VECTOR
    __interrupt void port1_isr(void)
    {
    if (P1IFG & BIT3)
    {
    for(int i=0; i<10; i++);
    CCR1 += 15;
    if (CCR1 > 195)
    CCR1 = 0;
    P1IFG &= ~BIT3;
    }
    }

    这是lcd1602的程序






    #include <intrinsics.h>
    #include <msp430g2253.h>
    #include <msp430.h>
    /*****************************************************
    端口定义
    ****************************************************/
    #define LCD_EN_PORT P1OUT //以下2个要设为同一个口
    #define LCD_EN_DDR P1DIR
    #define LCD_RS_PORT P1OUT //以下2个要设为同一个口
    #define LCD_RS_DDR P1DIR
    #define LCD_DATA_PORT P2OUT //以下3个要设为同一个口
    #define LCD_DATA_DDR P2DIR //一定要用高4位
    #define LCD_RS BIT6
    #define LCD_EN BIT7
    #define LCD_DATA BIT7|BIT6|BIT5|BIT4 //4位数据线连接模式
    /***************************************************
    预定义函数
    **************************************************/
    void LCD_init(void);
    void LCD_init_first(void);
    void LCD_en_write1(void); //上升沿使能
    void LCD_en_write2(void); //下降沿使能
    void LCD_write_command(unsigned char command);
    void LCD_write_data(unsigned char data);
    void LCD_set_xy (unsigned char x, unsigned char y);
    void LCD_write_string(unsigned char X,unsigned char Y, unsigned char *s);
    void LCD_write_char(unsigned char X,unsigned char Y, unsigned char data);
    void delay_1ms(void);
    void delay_nus(unsigned int n);
    void delay_nms(unsigned int n);
    /********************************************
    LCD液晶操作函数
    *******************************************/
    void LCD_init_first(void) //LCD1602液晶初始化函数(热启动)
    {
    delay_nms(500);
    LCD_DATA_DDR|=LCD_DATA; //数据口方向为输出
    LCD_EN_DDR|=LCD_EN; //设置EN方向为输出
    LCD_RS_DDR|=LCD_RS; //设置RS方向为输出
    delay_nms(50);
    LCD_write_command(0x30);
    delay_nms(50);
    LCD_write_command(0x30);
    delay_nms(5);
    LCD_write_command(0x30);
    delay_nms(500);
    }
    /*****************************************
    *
    * LCD1602液晶初始化函数
    *
    ****************************************/
    void LCD_init(void)
    {
    delay_nms(500);
    LCD_DATA_DDR|=LCD_DATA; //数据口方向为输出
    LCD_EN_DDR|=LCD_EN; //设置EN方向为输出
    LCD_RS_DDR|=LCD_RS; //设置RS方向为输出
    delay_nms(500);
    LCD_write_command(0x28); //4位数据接口
    delay_nms(50);
    LCD_write_command(0x28); //4位数据接口
    delay_nms(50);
    LCD_write_command(0x28); //4位数据接口
    delay_nms(50);
    LCD_en_write2();
    delay_nms(50);
    LCD_write_command(0x28); //4位数据接口
    delay_nms(500);
    LCD_write_command(0x01); //清屏
    LCD_write_command(0x0c); //显示开,关光标,不闪烁
    LCD_write_command(0x06); //设定输入方式,增量不移位
    delay_nms(50);
    }
    /*****************************************
    *
    * 液晶使能上升沿
    *
    ****************************************/
    void LCD_en_write1(void)
    {
    LCD_EN_PORT&=~LCD_EN;
    delay_nus(10);
    LCD_EN_PORT|=LCD_EN;
    }
    /*****************************************
    *
    * 液晶使能下降沿
    *
    ****************************************/
    void LCD_en_write2(void)
    {
    LCD_EN_PORT|=LCD_EN;
    delay_nus(10);
    LCD_EN_PORT&=~LCD_EN;
    }
    /*****************************************
    *
    * 写指令函数
    *
    ****************************************/
    void LCD_write_command(unsigned char command)
    {
    delay_nus(16);
    P2SEL=0x00;
    LCD_RS_PORT&=~LCD_RS; //RS=0
    LCD_en_write1();
    LCD_DATA_PORT&=0X0f; //清高四位
    LCD_DATA_PORT|=command&0xf0; //写高四位
    delay_nus(16);
    LCD_en_write2();
    command=command<<4; //低四位移到高四位
    LCD_en_write1();
    LCD_DATA_PORT&=0x0f; //清高四位
    LCD_DATA_PORT|=command&0xf0; //写低四位
    LCD_en_write2();
    }
    /*****************************************
    *
    * 写数据函数
    *
    ****************************************/
    void LCD_write_data(unsigned char data)
    {
    delay_nus(16);
    P2SEL=0x00;
    LCD_RS_PORT|=LCD_RS; //RS=1
    LCD_en_write1(); //E上升沿
    LCD_DATA_PORT&=0X0f; //清高四位
    LCD_DATA_PORT|=data&0xf0; //写高四位
    delay_nus(16);
    LCD_en_write2();
    data=data<<4; //低四位移到高四位
    LCD_en_write1();
    LCD_DATA_PORT&=0X0f; //清高四位
    LCD_DATA_PORT|=data&0xf0; //写低四位
    LCD_en_write2();
    }
    /*****************************************
    *
    * 写地址函数
    *
    ****************************************/
    void LCD_set_xy( unsigned char x, unsigned char y )
    {
    unsigned char address;
    if (y == 0) address = 0x80 + x;
    else address = 0xc0 + x;
    LCD_write_command( address);
    }
    /*****************************************
    *
    *LCD在任意位置写字符串,列x=0~15,行y=0,1
    *
    ****************************************/
    void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s)
    {
    LCD_set_xy( X, Y ); //写地址
    while (*s) //写显示字符
    {
    LCD_write_data( *s );
    s++;
    }
    }
    /*****************************************
    *
    * LCD在任意位置写字符,列x=0~15,行y=0,1
    *
    ****************************************/
    void LCD_write_char(unsigned char X,unsigned char Y,unsigned char data)
    {
    LCD_set_xy( X, Y ); //写地址
    LCD_write_data( data);
    }
    /*****************************************
    *
    * 1us延时函数
    *
    ****************************************/
    void delay_1us(void)
    {
    asm("nop");
    }
    /*****************************************
    *
    * N us延时函数
    *
    ****************************************/
    void delay_nus(unsigned int n)
    {
    unsigned int i;
    for (i=0;i<n;i++)
    delay_1us();
    }
    /*****************************************
    *
    * 1ms延时函数
    *
    ****************************************/
    void delay_1ms(void)
    {
    unsigned int i;
    for (i=0;i<1140;i++);
    }
    /*****************************************
    *
    * N ms延时函数
    *
    ****************************************/
    void delay_nms(unsigned int n)
    {
    unsigned int i=0;
    for (i=0;i<n;i++)
    delay_1ms();
    }


  • 谢谢您的解答,我找出问题了,

    ADC10AE0 |=BIT0+BIT1+BIT3; //打开模拟输入通道

    这里已经用过p1.3口了

    adc配置IO口是否会影响IO口的SEL的选择?

    比如设置某个脚为模拟输入通道然后这个脚的SEL就不起作用了

  • 配置成第二功能后,GPIO就失效了。