基于MSP430F149单片机的直流电压测试仪设计的源代码,要求:(1)利用MSP430单片机中的A/D外设,测量0-3V直流电压 (2)显示精度0.01V 外部参考电源:测量0-3V内部参考电源:测量0-2.5V(3)3位数字用LCD1602显示
时间: 2024-05-06 11:16:14 浏览: 94
基于单片机直流电压检测系统设计
下面是基于MSP430F149单片机的直流电压测试仪设计的源代码,可以参考一下:
```c
#include <msp430.h>
#include <stdio.h>
#define LCD_EN BIT2
#define LCD_RS BIT3
#define LCD_D4 BIT4
#define LCD_D5 BIT5
#define LCD_D6 BIT6
#define LCD_D7 BIT7
#define LCD_PORT P2OUT
#define LCD_DDR P2DIR
void LCD_SendNibble(unsigned char nibble)
{
LCD_PORT &= ~(LCD_D4 + LCD_D5 + LCD_D6 + LCD_D7);
LCD_PORT |= nibble << 4;
LCD_PORT |= LCD_EN;
__delay_cycles(1000);
LCD_PORT &= ~LCD_EN;
}
void LCD_SendByte(unsigned char data, unsigned char rs)
{
if(rs) LCD_PORT |= LCD_RS;
else LCD_PORT &= ~LCD_RS;
LCD_SendNibble(data >> 4);
LCD_SendNibble(data & 0x0F);
}
void LCD_Init()
{
LCD_DDR |= LCD_EN + LCD_RS + LCD_D4 + LCD_D5 + LCD_D6 + LCD_D7;
__delay_cycles(15000);
LCD_SendNibble(0x03);
__delay_cycles(5000);
LCD_SendNibble(0x03);
__delay_cycles(100);
LCD_SendNibble(0x03);
LCD_SendNibble(0x02);
LCD_SendByte(0x28, 0); // 4-bit, 2-line, 5x8 font
LCD_SendByte(0x0C, 0); // display on, cursor off, blink off
LCD_SendByte(0x06, 0); // cursor right, no shift
LCD_SendByte(0x01, 0); // clear display
}
void LCD_Print(char *str)
{
while(*str)
{
LCD_SendByte(*str++, 1);
}
}
void ADC_Init()
{
ADC12CTL0 = ADC12ON + ADC12SHT0_8 + ADC12MSC; // turn on ADC, set sample time, enable multiple sample and conversion
ADC12CTL1 = ADC12SHP + ADC12CONSEQ_3; // sampling timer, repeat-sequence-of-channels mode
ADC12CTL2 = ADC12RES_2; // 12-bit resolution
ADC12MCTL0 = ADC12SREF_1 + ADC12INCH_0; // Vref+ = VCC, Vref- = AVss, A0 channel
ADC12MCTL1 = ADC12SREF_1 + ADC12INCH_1 + ADC12EOS; // Vref+ = VCC, Vref- = AVss, A1 channel, end of sequence
ADC12IE = BIT1; // enable interrupt for channel 1
ADC12CTL0 |= ADC12ENC; // enable conversion
__delay_cycles(100000); // delay for reference voltage settling
}
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
BCSCTL1 = CALBC1_16MHZ; // set DCO to 16MHz
DCOCTL = CALDCO_16MHZ;
LCD_Init();
ADC_Init();
__enable_interrupt();
while(1)
{
ADC12CTL0 |= ADC12SC; // start conversion
__bis_SR_register(LPM0_bits + GIE); // go to sleep mode and wait for interrupt
}
}
#pragma vector=ADC12_VECTOR
__interrupt void ADC12ISR(void)
{
char buffer[16];
if(ADC12IFG & BIT1) // channel 1 interrupt
{
int result = ADC12MEM1;
float voltage = (float) result / 4096 * 2.5; // convert to voltage
sprintf(buffer, "%.2fV", voltage); // format voltage value with 2 decimal places
LCD_SendByte(0x01, 0); // clear display
LCD_Print(buffer); // display voltage value
}
ADC12IFG = 0; // clear interrupt flag
__bic_SR_register_on_exit(LPM0_bits); // exit sleep mode
}
```
说明:
1. 引入头文件和定义一些常量和函数。
2. 定义LCD_SendNibble函数,用于发送4位数据到LCD。
3. 定义LCD_SendByte函数,用于发送一个字节的数据到LCD,rs参数指定数据还是命令。
4. 定义LCD_Init函数,用于初始化LCD。
5. 定义LCD_Print函数,用于在LCD上打印字符串。
6. 定义ADC_Init函数,用于初始化ADC。
7. 在main函数中初始化LCD和ADC,并启用中断。
8. 在while循环中启动ADC转换。
9. 定义ADC12ISR函数,用于处理ADC中断。获取测量结果并转换为电压值,然后在LCD上显示。
需要注意的是,为了使LCD正常工作,需要连接一个4.7k欧姆的电阻从VCC到LCD的RS和EN引脚。另外,为了获取更精确的电压值,可以增加采样次数,或者使用差分采样来消除偏置。
阅读全文