ATmega328PB 사용 (3) PWM으로 LED를 켜기
14289 단어 임베디드ATmega328PB초보자PWM
처음에
LED 조광에 PWM을 사용하므로 테스트 프로그램으로 동작 확인해 봅니다.
PWM 모드
ATMega328PB 타이머의 동작 모드에는 표준(Normal), 위상 보정 PWM(PWM,PhaseCorrect), CTC, 고속 PWM(Fast PWM) 모드가 있습니다.
TC0이면 동작 모드나 TOP값 등의 조합으로 아래 표와 같은 모드를 선택할 수 있습니다.
LED 조광을 위해 고속 PWM에서 TOP 값 0xFF의 Mode 3을 설정합니다.
16bit 타이머의 TC1등에서는 9bit, 10bit도 선택할 수 있습니다만. 모두 8bit로 하고 있습니다.
클록은 8MHz의 256분주로 했다. PWM의주기는 약 8.2ms입니다.
PWM 배치
PWM0~3을 추가합니다. 다만 다른 용도로 사용하는 포트와 부딪치므로 모두 사용할 수 없습니다.
이번 PWM3에 할당한 TC3의 OCA는 다른 포트(UART)와 배팅하므로 OCB만 PWM으로 사용합니다.
구성 요소 설정
TC3/TC4를 PWM 출력으로 사용하는 경우에는 주의가 필요합니다.
TC3/TC4는 Output Compare Modulator에 연결되어 있습니다.
따라서 TC3/TC4를 별도의 PWM 출력으로 사용할 수 없습니다. 또한 Modulator 설정에 PD2를 사용합니다.
TC3을 PWM 출력으로 하려면 PD2를 출력으로 하고 '1'을 설정합니다.
코드
7개의 PWM을 동시에 변화시키는 코드입니다.
PWM의 초기 설정 후, 타이머로 밝기를 변화시키고 있습니다.
#define NUMBER_OF_PWM (7)
uint16_t PwmTbl[] ={
0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,
90, 80, 70, 60, 50, 40, 30, 20, 10
};
int PwmTblSize;
static uint8_t PwmStage[NUMBER_OF_PWM];
static uint16_t PwmTopVal;
void PWM_0AB_init(void)
{
// Enable pin output
PWM_0_enable_output_ch0();
PWM_0_enable_output_ch1();
// Set channel 0 duty cycle value register value to specified value
PWM_0_load_duty_cycle_ch0(0x3f);
PWM_0_load_duty_cycle_ch1(0x3f);
// Set counter register value
PWM_0_load_counter(0);
}
void PWM_1AB_init(void)
{
// Enable pin output
PWM_1_enable_output_ch0();
PWM_1_enable_output_ch1();
// Set channel 0 duty cycle value register value to specified value
PWM_1_load_duty_cycle_ch0(0x3f);
PWM_1_load_duty_cycle_ch1(0x3f);
// Set counter register value
PWM_1_load_counter(0);
}
void PWM_2AB_init(void)
{
// Enable pin output
PWM_2_enable_output_ch0();
PWM_2_enable_output_ch1();
// Set channel 0 duty cycle value register value to specified value
PWM_2_load_duty_cycle_ch0(0x3f);
PWM_2_load_duty_cycle_ch1(0x3f);
// Set counter register value
PWM_2_load_counter(0);
}
void PWM_3AB_init(void)
{
PWM_3_enable();
// Enable pin output
PWM_3_enable_output_ch1();
// Set channel 0 duty cycle value register value to specified value
PWM_3_load_duty_cycle_ch1(0x3f);
// Set counter register value
PWM_3_load_counter(0);
}
void timerIntr(void)
{
static unsigned int count = 0;
uint16_t width[NUMBER_OF_PWM];
count++;
if (count >= 400) {
count = 0;
for (int i = 0;i < NUMBER_OF_PWM; i++) {
PwmStage[i]++;
if (PwmStage[i] >= PwmTblSize) {
PwmStage[i] = 0;
}
width[i] = ((uint16_t)PwmTopVal*(uint16_t)PwmTbl[PwmStage[i]]);
width[i] /= 100;
}
PWM_0_load_duty_cycle_ch0((PWM_0_register_t)width[0]);
PWM_0_load_duty_cycle_ch1((PWM_0_register_t)width[1]);
PWM_1_load_duty_cycle_ch0((PWM_1_register_t)width[2]);
PWM_1_load_duty_cycle_ch1((PWM_1_register_t)width[3]);
PWM_2_load_duty_cycle_ch0((PWM_2_register_t)width[4]);
PWM_2_load_duty_cycle_ch1((PWM_2_register_t)width[5]);
PWM_3_load_duty_cycle_ch1((PWM_3_register_t)width[6]);
}
}
int main(void)
{
/* Initializes MCU, drivers and middleware */
atmel_start_init();
PwmTblSize = sizeof(PwmTbl)/sizeof(uint16_t);
PwmTopVal = 0xff;
PwmStage[0] = 0;
PwmStage[1] = 0;
PwmStage[2] = 0;
PwmStage[3] = 0;
PwmStage[4] = 0;
PwmStage[5] = 0;
PwmStage[6] = 0;
PWM_0AB_init();
PWM_1AB_init();
PWM_2AB_init();
PWM_3AB_init();
/* Replace with your application code */
while (1) {
;
}
}
내용에 미비 등이 있으면 연락 부탁드립니다.
Reference
이 문제에 관하여(ATmega328PB 사용 (3) PWM으로 LED를 켜기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/toshidln/items/406f60c534b6ecc7c9e6
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
ATMega328PB 타이머의 동작 모드에는 표준(Normal), 위상 보정 PWM(PWM,PhaseCorrect), CTC, 고속 PWM(Fast PWM) 모드가 있습니다.
TC0이면 동작 모드나 TOP값 등의 조합으로 아래 표와 같은 모드를 선택할 수 있습니다.
LED 조광을 위해 고속 PWM에서 TOP 값 0xFF의 Mode 3을 설정합니다.
16bit 타이머의 TC1등에서는 9bit, 10bit도 선택할 수 있습니다만. 모두 8bit로 하고 있습니다.
클록은 8MHz의 256분주로 했다. PWM의주기는 약 8.2ms입니다.
PWM 배치
PWM0~3을 추가합니다. 다만 다른 용도로 사용하는 포트와 부딪치므로 모두 사용할 수 없습니다.
이번 PWM3에 할당한 TC3의 OCA는 다른 포트(UART)와 배팅하므로 OCB만 PWM으로 사용합니다.
구성 요소 설정
TC3/TC4를 PWM 출력으로 사용하는 경우에는 주의가 필요합니다.
TC3/TC4는 Output Compare Modulator에 연결되어 있습니다.
따라서 TC3/TC4를 별도의 PWM 출력으로 사용할 수 없습니다. 또한 Modulator 설정에 PD2를 사용합니다.
TC3을 PWM 출력으로 하려면 PD2를 출력으로 하고 '1'을 설정합니다.
코드
7개의 PWM을 동시에 변화시키는 코드입니다.
PWM의 초기 설정 후, 타이머로 밝기를 변화시키고 있습니다.
#define NUMBER_OF_PWM (7)
uint16_t PwmTbl[] ={
0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,
90, 80, 70, 60, 50, 40, 30, 20, 10
};
int PwmTblSize;
static uint8_t PwmStage[NUMBER_OF_PWM];
static uint16_t PwmTopVal;
void PWM_0AB_init(void)
{
// Enable pin output
PWM_0_enable_output_ch0();
PWM_0_enable_output_ch1();
// Set channel 0 duty cycle value register value to specified value
PWM_0_load_duty_cycle_ch0(0x3f);
PWM_0_load_duty_cycle_ch1(0x3f);
// Set counter register value
PWM_0_load_counter(0);
}
void PWM_1AB_init(void)
{
// Enable pin output
PWM_1_enable_output_ch0();
PWM_1_enable_output_ch1();
// Set channel 0 duty cycle value register value to specified value
PWM_1_load_duty_cycle_ch0(0x3f);
PWM_1_load_duty_cycle_ch1(0x3f);
// Set counter register value
PWM_1_load_counter(0);
}
void PWM_2AB_init(void)
{
// Enable pin output
PWM_2_enable_output_ch0();
PWM_2_enable_output_ch1();
// Set channel 0 duty cycle value register value to specified value
PWM_2_load_duty_cycle_ch0(0x3f);
PWM_2_load_duty_cycle_ch1(0x3f);
// Set counter register value
PWM_2_load_counter(0);
}
void PWM_3AB_init(void)
{
PWM_3_enable();
// Enable pin output
PWM_3_enable_output_ch1();
// Set channel 0 duty cycle value register value to specified value
PWM_3_load_duty_cycle_ch1(0x3f);
// Set counter register value
PWM_3_load_counter(0);
}
void timerIntr(void)
{
static unsigned int count = 0;
uint16_t width[NUMBER_OF_PWM];
count++;
if (count >= 400) {
count = 0;
for (int i = 0;i < NUMBER_OF_PWM; i++) {
PwmStage[i]++;
if (PwmStage[i] >= PwmTblSize) {
PwmStage[i] = 0;
}
width[i] = ((uint16_t)PwmTopVal*(uint16_t)PwmTbl[PwmStage[i]]);
width[i] /= 100;
}
PWM_0_load_duty_cycle_ch0((PWM_0_register_t)width[0]);
PWM_0_load_duty_cycle_ch1((PWM_0_register_t)width[1]);
PWM_1_load_duty_cycle_ch0((PWM_1_register_t)width[2]);
PWM_1_load_duty_cycle_ch1((PWM_1_register_t)width[3]);
PWM_2_load_duty_cycle_ch0((PWM_2_register_t)width[4]);
PWM_2_load_duty_cycle_ch1((PWM_2_register_t)width[5]);
PWM_3_load_duty_cycle_ch1((PWM_3_register_t)width[6]);
}
}
int main(void)
{
/* Initializes MCU, drivers and middleware */
atmel_start_init();
PwmTblSize = sizeof(PwmTbl)/sizeof(uint16_t);
PwmTopVal = 0xff;
PwmStage[0] = 0;
PwmStage[1] = 0;
PwmStage[2] = 0;
PwmStage[3] = 0;
PwmStage[4] = 0;
PwmStage[5] = 0;
PwmStage[6] = 0;
PWM_0AB_init();
PWM_1AB_init();
PWM_2AB_init();
PWM_3AB_init();
/* Replace with your application code */
while (1) {
;
}
}
내용에 미비 등이 있으면 연락 부탁드립니다.
Reference
이 문제에 관하여(ATmega328PB 사용 (3) PWM으로 LED를 켜기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/toshidln/items/406f60c534b6ecc7c9e6
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
#define NUMBER_OF_PWM (7)
uint16_t PwmTbl[] ={
0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100,
90, 80, 70, 60, 50, 40, 30, 20, 10
};
int PwmTblSize;
static uint8_t PwmStage[NUMBER_OF_PWM];
static uint16_t PwmTopVal;
void PWM_0AB_init(void)
{
// Enable pin output
PWM_0_enable_output_ch0();
PWM_0_enable_output_ch1();
// Set channel 0 duty cycle value register value to specified value
PWM_0_load_duty_cycle_ch0(0x3f);
PWM_0_load_duty_cycle_ch1(0x3f);
// Set counter register value
PWM_0_load_counter(0);
}
void PWM_1AB_init(void)
{
// Enable pin output
PWM_1_enable_output_ch0();
PWM_1_enable_output_ch1();
// Set channel 0 duty cycle value register value to specified value
PWM_1_load_duty_cycle_ch0(0x3f);
PWM_1_load_duty_cycle_ch1(0x3f);
// Set counter register value
PWM_1_load_counter(0);
}
void PWM_2AB_init(void)
{
// Enable pin output
PWM_2_enable_output_ch0();
PWM_2_enable_output_ch1();
// Set channel 0 duty cycle value register value to specified value
PWM_2_load_duty_cycle_ch0(0x3f);
PWM_2_load_duty_cycle_ch1(0x3f);
// Set counter register value
PWM_2_load_counter(0);
}
void PWM_3AB_init(void)
{
PWM_3_enable();
// Enable pin output
PWM_3_enable_output_ch1();
// Set channel 0 duty cycle value register value to specified value
PWM_3_load_duty_cycle_ch1(0x3f);
// Set counter register value
PWM_3_load_counter(0);
}
void timerIntr(void)
{
static unsigned int count = 0;
uint16_t width[NUMBER_OF_PWM];
count++;
if (count >= 400) {
count = 0;
for (int i = 0;i < NUMBER_OF_PWM; i++) {
PwmStage[i]++;
if (PwmStage[i] >= PwmTblSize) {
PwmStage[i] = 0;
}
width[i] = ((uint16_t)PwmTopVal*(uint16_t)PwmTbl[PwmStage[i]]);
width[i] /= 100;
}
PWM_0_load_duty_cycle_ch0((PWM_0_register_t)width[0]);
PWM_0_load_duty_cycle_ch1((PWM_0_register_t)width[1]);
PWM_1_load_duty_cycle_ch0((PWM_1_register_t)width[2]);
PWM_1_load_duty_cycle_ch1((PWM_1_register_t)width[3]);
PWM_2_load_duty_cycle_ch0((PWM_2_register_t)width[4]);
PWM_2_load_duty_cycle_ch1((PWM_2_register_t)width[5]);
PWM_3_load_duty_cycle_ch1((PWM_3_register_t)width[6]);
}
}
int main(void)
{
/* Initializes MCU, drivers and middleware */
atmel_start_init();
PwmTblSize = sizeof(PwmTbl)/sizeof(uint16_t);
PwmTopVal = 0xff;
PwmStage[0] = 0;
PwmStage[1] = 0;
PwmStage[2] = 0;
PwmStage[3] = 0;
PwmStage[4] = 0;
PwmStage[5] = 0;
PwmStage[6] = 0;
PWM_0AB_init();
PWM_1AB_init();
PWM_2AB_init();
PWM_3AB_init();
/* Replace with your application code */
while (1) {
;
}
}
Reference
이 문제에 관하여(ATmega328PB 사용 (3) PWM으로 LED를 켜기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/toshidln/items/406f60c534b6ecc7c9e6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)