Chúng tôi không thể tạo tín hiệu sin đúng cách bằng vi điều khiển MC68HC908GP32 . Mô tả về PWM bắt đầu ở trang 349. Tần số xung nhịp là 2,4 MHz, trong khi chúng tôi đã sử dụng PWM 7 kHz bằng cách sử dụng bộ đếm gộp trước và đặt modulo hẹn giờ thành 350 như sau:
T1SC = 0x60; // Prescaler: Div entre 64
//Counter modulo = 0x015E = 350
T1MODH = 0x01; // High
T1MODL = 0x5E; // Low
Đầu ra PWM được lọc bởi bộ lọc RLC sau, và sau đó DC được loại bỏ bằng cách sử dụng nắp 1uF loạt. Tần số cắt là cách dưới 7kHz của PWM.
Đầu tiên, chúng tôi đã thử sử dụng LUT, mẫu nào được tạo bằng trang này (100 mẫu, biên độ = 250). Điều này bao gồm một giai đoạn duy nhất.
int seno[100]={ 125, 133, 141, 148, 156, 164, 171, 178, 185, 192, 198, 205, 211, 216, 221, 226, 231, 235, 238, 241, 244, 246, 248, 249, 250, 250, 250, 249, 248, 246, 244, 241, 238, 235, 231, 226, 221, 216, 211, 205, 198, 192, 185, 178, 171, 164, 156, 148, 141, 133, 125, 117, 109, 102, 94, 86, 79, 72, 65, 58, 52, 45, 39, 34, 29, 24, 19, 15, 12, 9, 6, 4, 2, 1, 0, 0, 0, 1, 2, 4, 6, 9, 12, 15, 19, 24, 29, 34, 39, 45, 52, 58, 65, 72, 79, 86, 94, 102, 109, 117};
Độ rộng của xung sau được tính sau mỗi chu kỳ PWM:
interrupt 4 void rsi_t1ch0 (void)
{
//-- disable interruption flag
T1SC0&=(~0x80);
//-- pwm to '0'
PTB&=0xFD;
//some sensor measures are done here.... 100 out of the 350 cycles are left for this
}
/************************************************************/
/* TIM1 overflow rutine */
/************************************************************/
interrupt 6 void rsi_ov1 (void)
{
T1SC&=(~0x80);
//-- set PWM to 1
PTB|=0x02;
T1CH0H = ((seno[fase])>>8); // high bits
T1CH0L = (seno[fase])&0xFF; // low bits
fase+=1;
if (fase >= 99)
fase=0;
}
void main(void)
{
float temp;
int i;
CONFIG1|=0x01;
DDRB=0xFF; //-- Port B is set as output
PTB=0x00;
//Timer setup
T1SC = 0x60; // Prescaler: Div by 64
T1MODH = 0x01; //Counter modulo
T1MODL = 0x5E;
T1SC0 = 0x50; //Comparator setup
//-- Initial width
T1CH0H = 0x00;
T1CH0L = 0x53;
EnableInterrupts;
T1SC&=~(0x20); //Run timer forever
for(;;);
}
Khi cắm nó vào phạm vi, chúng ta nhận được tín hiệu sau. Chúng tôi không thể tránh được đỉnh kỳ lạ đó gần mức tối thiểu.
Khi phóng to xung quanh đỉnh đó, chúng ta có thể thấy đầu ra của PWM (lên) trên thực tế không chính xác.
Vì vậy, sau khi loay hoay một lúc và không thể thoát khỏi nó, chúng tôi đã thử tính toán tín hiệu sin trong MCU, thay vì mã hóa cứng giá trị cho từng mẫu. Chúng tôi đã thêm đoạn mã sau vào chức năng chính, ngay trước khi tất cả các thiết lập bộ đếm:
for(i=0;i<99;i++) {
temp=100*(sin(2*3.14159*i/100)+1);
seno[i]=(int)temp;
}
Nhưng kết quả thậm chí không giống như một hình sin:
Sau nhiều giờ vật lộn với nó, chúng tôi đã không thể tìm ra sai lầm của mình. Chúng tôi sẽ đánh giá cao một lời khuyên.