Cách này tuy đúng nhưng không nên dùng. Vì tập lệnh MCU (Lệnh Assembly) thường có sẵn các lệnh dịch bit, còn cách lệnh toán thì cùng lắm chỉ hỗ trợ đến cộng/trừ . Do vậy, chuyển lệnh dịch bit sang các lệnh nhân/chia làm lãng phí tài nguyên (Bộ nhớ+Thời gian xử lý) của hệ thốngTheo mình để dịch trái bit thì mình có thể nhân 2.
P1OUT+=P1OUT;
Dịch phải thì có thể chia 2
P1OUT/=2;
ủa sao em copy i chang mà cái mạch e nó đơ như cây cơ ???Sau khi xem mấy cái post mình có đóng góp thế này:Tình hình là hôm nay mới nhận kit về và rất thích thú với việc vọc em nó. Tuy nhiên, vì mới làm quen với lập trình C cho MSP430 nên mình còn khá bỡ ngỡ. Vì vậy mình xin lập topic này để các bạn newmem như mình có thể trao đổi, thảo luận và học hỏi thêm.
Đầu tiên là mình hỏi về lệch dịch bit. Mình định làm dàn Led trong mạch chạy qua chạy lại, nhưng không biết cấu trúc của lệnh dịch là gì. Mình định xuất ra P1.
Cái thứ 2 là mình định cho P1.i với i chạy từ 0->7, như vậy có lệnh nào thực hiện điều đó không?
Ví dụ nếu viết theo pascal là
for i:=0 to 7 do
P1.i := 1;
Vì con msp430g nó không có thanh ghi bit cho 1 PORT như trên PIC, hình như muốn xuất giá trị thì chỉ tác động lên P1OUT nên không thể dùng phép gắn cho cả PORT được.
Code gợi ý của mình như sau
Với đoạn code trên thì nó sẽ thực hiện cháy từng led trên PORT LED, cứ sau 1 ms thì cháy 1 con theo thứ tự dịch sang trái (chú ý là do LED trên MAIN kích bằng mức 0 nên với code này nó sẽ sáng hết 7 led và chỉ tắt 1 led thôi)Code:P1DIR |= 0xFF; // Set mode out mode cho P1 P1SEL = 0; // Set mode GPIO P1SEL2 = 0; P1OUT &= ~0xFF; // Reset all pins while (1) { unsigned char i, temp = 0x01; for (i=0; i<8; i++) { P1OUT &= ~0xFF; // Reset all pins P1OUT |= temp; // Set pins temp = temp << 1; _delay_cycles(100000); // Delay 100 ms } }
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
ò hjhj chạy đc òi ủa mà cái lệnh trên có ý nghĩa như thế nào a?Bạn đã tắt WatchDog Timer chưa vậy? Nếu không tắt thì sẽ không chạy được đâu.
Code:// Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD;
void main(void)
{
P1DIR |= BIT0;
P1DIR |= BIT6;
WDTCTL = WDTPW + WDTHOLD;
for (;;)
{
volatile unsigned int i;
P1OUT ^= BIT0|BIT6;
i = 50000;
do (i--);
while (i != 0);
}
}
WDTCTL = WDTPW + WDTHOLD;
Nhìn code là thấy dân pro rồi :(.. CLB ta sắp có nhân tài mớiò hjhj chạy đc òi ủa mà cái lệnh trên có ý nghĩa như thế nào a?Bạn đã tắt WatchDog Timer chưa vậy? Nếu không tắt thì sẽ không chạy được đâu.
Code:// Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD;
nếu e để nó trong code trên thì hai đền nhấp nháy có độ dừng, còn nếu ko có thì nhấp nháy liên tục???Code:void main(void) { P1DIR |= BIT0; P1DIR |= BIT6; WDTCTL = WDTPW + WDTHOLD; for (;;) { volatile unsigned int i; P1OUT ^= BIT0|BIT6; i = 50000; do (i--); while (i != 0); } }
úi giời ạ copy cái này liếc cái kia mới ra cái code trên áNhìn code là thấy dân pro rồi :(.. CLB ta sắp có nhân tài mớiò hjhj chạy đc òi ủa mà cái lệnh trên có ý nghĩa như thế nào a?Bạn đã tắt WatchDog Timer chưa vậy? Nếu không tắt thì sẽ không chạy được đâu.
Code:// Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD;
nếu e để nó trong code trên thì hai đền nhấp nháy có độ dừng, còn nếu ko có thì nhấp nháy liên tục???Code:void main(void) { P1DIR |= BIT0; P1DIR |= BIT6; WDTCTL = WDTPW + WDTHOLD; for (;;) { volatile unsigned int i; P1OUT ^= BIT0|BIT6; i = 50000; do (i--); while (i != 0); } }
à dậy chu kì nháy của nó mặc định là nhiêu a?dòngdùng để tắt WatchDog Timer nếu để nó còn hoạt động thì cứ sau một thời gian khi mà WatchDog Timer ràn thì nó sẽ tự động reset lại vdk nên code của em viết không có dòng đó thì sẽ bị reset liên tục. nên sẽ xin ra hiện tượng nháy liên tục.Code:WDTCTL = WDTPW + WDTHOLD;
#include <msp430g2553.h>
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;
P1DIR |= BIT0;
P1DIR |= BIT6;
for (;;)
{
{
volatile unsigned int i;
P1OUT ^= BIT0|BIT6;
i = 50000;
do (i--);
while (i != 0);
}
_delay_cycles(10000000);
}
}
phải dùng lệnh máy thôi...go to.. mà hình như không ai xài nhiềuà, cho mình hỏi chút: cái lệnh nhảy đến nhãn cho trước trong đây là gì vậy? Vd trong 8051 là sjmp....
"Never use goto statement" : các lập trình viên ở ngôn ngữ cấp cao thường nhắc nhau như vậyà, cho mình hỏi chút: cái lệnh nhảy đến nhãn cho trước trong đây là gì vậy? Vd trong 8051 là sjmp....
Nhìn có vẻ là hợp lí. Nhưng nếu muốn xuất PWM cần config cho chân P1.6 nữacho hỏi làm thế nào để config 2 timer, Timer A0 xùng xuất PWM qua chân p1.6.
Timer A1 đếm lên trong vòng 25ms.
anh em chỉ giáo.
void ConfigTimer(void)
{
CCTL0=CCIE; //CCR0 interrupt enabled
TA0CTL = TASSEL_2 + MC_1; // SMCLK, up mode
}
void ConfigPWM(void)
{
CCR0=1000; // PWM Period=50HZ
CCTL1 = OUTMOD_7; // CCR1 reset/set
CCR1=0; // PWM duty cycle
}
///////////////////////////////////////////////////////////////////////
void Configdemxung (void)
{
TA1CCTL0 = CCIE; // CCR0 interrupt enabled
TA1CCR0 = 25000;
TA1CTL = TASSEL_2 + MC_1; // SMCLK, upmode
}
và ngắt như thế này thì trong có hợp lí không
#pragma vector=TIMER1_A0_VECTOR
__interrupt void Timer1_A0 (void)
{Speed = pulse - pre_pulse; //so xung trong 25ms
pre_pulse = pulse;
Speed = (Speed*40*60)/400;
}
Timer A1 ngắt trong vòng 25ms
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer0_A0 (void)
{
//CCR1=CCR1+1; // Increace Duty Cycle
//if(CCR1==1001) CCR1=0; // If Duty Cycle =100%, reset it
CCR1 = Output;
}
Timer a0 xuất pwm theo chu kì là CCR1