感谢TI送的LaunchPad,终于有时间发心德了
代码:
#include "msp430g2231.h"
#define UART_TXD 0x02 // TXD on P1.1 (Timer0_A.OUT0)
#define UART_RXD 0x04 // RXD on P1.2 (Timer0_A.CCI1A)
#define UART_TBIT_DIV_2 (1000000 / (9600 * 2))
#define UART_TBIT (1000000 / 9600)
unsigned int txData; // UART internal variable for TX
unsigned char rxBuffer; // Received UART character
unsigned char number_table[]={'0','1','2','3','4','5','6','7','8','9'};
unsigned char display_buffer[]={0x00,0x00,0x00,0x00,0xff};
unsigned int i;
unsigned long int t;
void TimerA_UART_init(void);
void TimerA_UART_tx(unsigned char byte);
void TimerA_UART_print(char *string);
void data_converter(unsigned char *p,unsigned int vaule); //数据变换
void send_data(unsigned char *p);//串行口发送数组
void ADC10_init(void);
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
DCOCTL = 0x00; // Set DCOCLK to 1MHz
BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;
P1OUT = 0x00; // Initialize all GPIO
P1SEL = UART_TXD + UART_RXD; // Timer function for TXD/RXD pins
P1DIR&=~UART_RXD;// Set all pins but RXD to output
P1DIR|=UART_TXD;
__enable_interrupt();
TimerA_UART_init();
ADC10_init();
for (;;)
{
t=0;
for(i=0;i<256;i++)
{
ADC10CTL0&=~ADC10IFG;
ADC10CTL0|=ENC+ADC10SC;
__delay_cycles(10);
while(!(ADC10CTL0&ADC10IFG));
t+=ADC10MEM;
}
t=t>>8;
TimerA_UART_print("%%");
data_converter(display_buffer,t); //数据变换
send_data(display_buffer);//发送数据
//TimerA_UART_print("\r\n");
//__bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
}
}
void TimerA_UART_init(void)
{
TACCTL0 = OUT; // Set TXD Idle as Mark = '1'
TACCTL1 = SCS + CM1 + CAP + CCIE; // Sync, Neg Edge, Capture, Int
TACTL = TASSEL_2 + MC_2; // SMCLK, start in continuous mode
}
//------------------------------------------------------------------------------
// Outputs one byte using the Timer_A UART
//------------------------------------------------------------------------------
void TimerA_UART_tx(unsigned char byte)
{
while (TACCTL0 & CCIE); // Ensure last char got TX'd
TACCR0 = TAR; // Current state of TA counter
TACCR0 += UART_TBIT; // One bit time till first bit
TACCTL0 = OUTMOD0 + CCIE; // Set TXD on EQU0, Int
txData = byte; // Load global variable
txData |= 0x100; // Add mark stop bit to TXData
txData <<= 1; // Add space start bit
}
//------------------------------------------------------------------------------
// Prints a string over using the Timer_A UART
//------------------------------------------------------------------------------
void TimerA_UART_print(char *string)
{
while (*string) {
TimerA_UART_tx(*string++);
}
}
//------------------------------------------------------------------------------
// Timer_A UART - Transmit Interrupt Handler
//------------------------------------------------------------------------------
#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A0_ISR(void)
{
static unsigned char txBitCnt = 10;
TACCR0 += UART_TBIT; // Add Offset to CCRx
if (txBitCnt == 0) { // All bits TXed?
TACCTL0 &= ~CCIE; // All bits TXed, disable interrupt
txBitCnt = 10; // Re-load bit counter
}
else {
if (txData & 0x01) {
TACCTL0 &= ~OUTMOD2; // TX Mark '1'
}
else {
TACCTL0 |= OUTMOD2; // TX Space '0'
}
txData >>= 1;
txBitCnt--;
}
}
//------------------------------------------------------------------------------
// Timer_A UART - Receive Interrupt Handler
//------------------------------------------------------------------------------
#pragma vector = TIMERA1_VECTOR
__interrupt void Timer_A1_ISR(void)
{
static unsigned char rxBitCnt = 8;
static unsigned char rxData = 0;
switch (__even_in_range(TAIV, TAIV_TAIFG)) { // Use calculated branching
case TAIV_TACCR1: // TACCR1 CCIFG - UART RX
TACCR1 += UART_TBIT; // Add Offset to CCRx
if (TACCTL1 & CAP) { // Capture mode = start bit edge
TACCTL1 &= ~CAP; // Switch capture to compare mode
TACCR1 += UART_TBIT_DIV_2; // Point CCRx to middle of D0
}
else {
rxData >>= 1;
if (TACCTL1 & SCCI) { // Get bit waiting in receive latch
rxData |= 0x80;
}
rxBitCnt--;
if (rxBitCnt == 0) { // All bits RXed?
rxBuffer = rxData; // Store in global variable
rxBitCnt = 8; // Re-load bit counter
TACCTL1 |= CAP; // Switch compare to capture mode
//__bic_SR_register_on_exit(LPM0_bits); // Clear LPM0 bits from 0(SR)
}
}
break;
}
}
//------------------------------------------------------------------------------
//**********************************************************************************
//数据变换
void data_converter(unsigned char *p,unsigned int value)
{
unsigned int m,n,j=0;
p[0]=number_table[value/1000];
m=value%1000;
p[1]=number_table[m/100];
n=m%100;
p[2]=number_table[n/10];
j=n%10;
p[3]=number_table[j/1];
}
//**********************************************************************************
//串行口发送数组
void send_data(unsigned char *p)
{
unsigned int n;
for(n=0;p[n]!=0xff;n++)
{
//while ((IFG1 & UTXIFG0) == 0); // USART0发送UTXIFG0=1,表示UTXBUF准备好发送一下字符
//TXBUF0 = p[n];
TimerA_UART_tx(p[n]);
_NOP();
_NOP();
}
}
void ADC10_init(void)
{
ADC10CTL0 &= ~ENC;
ADC10CTL0 = ADC10ON + ADC10SHT_3 + SREF_1+REFON;
ADC10CTL1 = CONSEQ_0 + ADC10SSEL_0 + ADC10DIV_0 + SHS_0 + INCH_7;
ADC10AE0 = 0x80;
ADC10CTL0 |= ENC;
}
说白了就是采集通过电位器分压的测速发电机的电压发到串口,数据采用%%XXXX的格式发送,TA UART 9600模拟串口
XXXX表是AD数据0-1023
上位机用VB写,串口代码
Private Sub MSComm1_OnComm()
Select Case MSComm1.CommEvent
Case comEvReceive
res1 = MSComm1.Input
t = Trim(res1)
'If (Len(t) < 3) Then Exit Sub
'If (Val(t) > 1024) Then Exit Sub
'MSComm1.InBufferCount = 0
'adc = Val(res1)
ss = InStr(1, res1, "%%")
If (ss < 1) Then
Exit Sub
MSComm1.InBufferCount = 0
Else
ssx = Right(res1, Len(res1) - (ss + 1))
End If
adc = Val(ssx)
adc = Val(ssx)
'Yx = ((adc - 673) * 423) / 1024
Yx = adc
'c = Yx
'Y = Yx * 100
Y = Yx * 14.6 / 4.54 '2.27
Form1.Caption = "转速" & CStr(Y) & "转/分钟"
Text2.text = Yx
End Select
End Sub
电路:
很简单就是分压电阻,把电压降低,送到AD(P1.7)
测试电机和测速发电机
这个还可以用来测人体电压
这个才是温度