You are on page 1of 3

#include <msp430.

h>
#include <stdio.h>

#define LCD_RS BIT0


#define LCD_E BIT1
#define LCD_D4 BIT4
#define LCD_D5 BIT5
#define LCD_D6 BIT6
#define LCD_D7 BIT7

#define IN1 BIT2


#define IN2 BIT3
#define UP BIT1
#define DOWN BIT2
#define ON_OFF BIT0

int speed = 0;

volatile unsigned long pulseWidth = 0; // Ðo r?ng xung ban d?u


void delay(int ms) {
int i, j;
for (i = 0; i < ms; i++)
for (j = 0; j < 1000; j++);
}
void LCD_nibble(unsigned char nibble) {
P1OUT &= ~(LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7);
P1OUT |= (nibble & 0x0F) << 4;
P1OUT |= LCD_E;
delay(1);
P1OUT &= ~LCD_E;
delay(1);
}
void LCD_command(unsigned char cmd) {
P1OUT &= ~LCD_RS;
LCD_nibble(cmd >> 4);
LCD_nibble(cmd);
delay(2);
}

void LCD_data(unsigned char data) {


P1OUT |= LCD_RS;
LCD_nibble(data >> 4);
LCD_nibble(data);
delay(2);
}

void LCD_init() {
P1DIR |= (LCD_RS | LCD_E | LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7);
P1OUT &= ~LCD_RS;
P1OUT &= ~LCD_E;
P1OUT &= ~(LCD_D4 | LCD_D5 | LCD_D6 | LCD_D7);

delay(100);

LCD_command(0x33);
LCD_command(0x32);
LCD_command(0x28);
LCD_command(0x0E);
LCD_command(0x01);
delay(2);
}

void LCD_clear() {
LCD_command(0x01);
delay(2);
}

void LCD_setPointer(unsigned char row, unsigned char col) {


unsigned char position = (row == 0) ? col : col + 0x40;
LCD_command(0x80 | position);
delay(2);
}

void LCD_display_string_at(char *str, int row, int col) {


LCD_setPointer(row, col);
while (*str) {
LCD_data(*str);
str++;
}
}

// C?u hình PWM


void ConfigurePWM()
{
TA0CCR0 = 10000; // Ð?t giá tr? t?i da cho chu k? PWM
TA0CCTL1 = OUTMOD_7; // Ch? d? PWM du?c d?t thành Reset/Set
TA0CCR1 = pulseWidth; // S? d?ng pulseWidth cho giá tr? PWM ban d?u
TA0CTL = TASSEL_2 + MC_1; // S? d?ng Timer A, ch? d? lên
TA0CCTL1 |= CCIE; // B?t c? cho ng?t so sánh cho kênh CCR1 c?a Timer A0
}

void main(void) {
WDTCTL = WDTPW | WDTHOLD; // T?t theo dõi
BCSCTL1 = CALBC1_1MHZ; // Ð?t t?n s? ho?t d?ng cho MSP430 là 1 MHz
DCOCTL = CALDCO_1MHZ; // Ð?t t?n s? DCO cho MSP430 là 1 MHz

P1SEL |= IN1 + IN2; // B?t ch? d? ch?c nang PWM cho các chân P1.2 (IN1) và P1.3
(IN2)
P1DIR |= (IN1 + IN2 ); // Ð?t là d?u ra
P1OUT &= ~(IN2 + IN1); // Xóa bit tuong ?ng c?a các chân P1.2 (IN1) và P1.3
(IN2)
P2REN |= (ON_OFF + + UP + DOWN); // B?t di?n tr? kéo lên
P2OUT |= (ON_OFF + UP + DOWN); // Ð?t m?c logic cao (1) cho các chân
P2DIR |= (ON_OFF + UP + DOWN); // Ð?t là d?u ra

LCD_init(); // Kh?i t?o LCD


LCD_display_string_at("TRANG THAI :",0,0);
LCD_display_string_at("DUTYCYCLE :", 1, 0);

while (1) // Hàm l?p


{
LCD_setPointer(2, 9); // Ð?t con tr? ? hàng 2, c?t 9
char speed_str[5]; // Khai báo m?t m?ng ký t? d? luu chu?i t?c d?

// Chuy?n d?i giá tr? pulseWidth thành chu?i và luu vào speed_str
sprintf(speed_str, "%04d",(pulseWidth)));
// In giá tr? t?c d? (s? d?ng LCD_display_string_at)
LCD_display_string_at(speed_str, 2, 9);

if (!(P2IN & ON_OFF))


{
ConfigurePWM();
if (!(P2IN & UP))
{
while (!(P2IN & UP));
if (pulseWidth < 10000 - 1000) {
pulseWidth += 1000;
}
}
if (!(P2IN & DOWN))
{
while (!(P2IN & DOWN));
if (pulseWidth >= 1) {
pulseWidth -= 1000;
}
}
}
else {
P1OUT &= ~(IN1 + IN2); // Ð?t IN1 và IN2 th?p
pulseWidth = 0;
}
__delay_cycles(1000); // Ð?i m?t chút tru?c khi ki?m tra l?i công t?c
}
}

You might also like