|
MC3PHAC+AVR, установка связи AVR c MC3PHAC поUART |
|
|
|
Jan 30 2011, 09:38
|
Группа: Новичок
Сообщений: 9
Регистрация: 20-10-10
Пользователь №: 60 297

|
Выкладываю драйвер для связи MC3PHAC и AVR
//***************************************************
// Драйвер управления MC3PHAC по UART *
// V1.0 30.01.2011 *
//***************************************************
//CodeVisionAVR V 2.03.4 Standart
//********************** UART ************************
#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7
#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)
#define RX_BUFFER_SIZE 64
#define TX_BUFFER_SIZE 64
char rx_buffer[RX_BUFFER_SIZE];
char tx_buffer[TX_BUFFER_SIZE];
unsigned char tx_wr_index,tx_rd_index,tx_counter=0;
unsigned char rx_wr_index=0,rx_rd_index,rx_counter=0;
bit rx_buffer_overflow;
// инициализация UART
void USART_init(){
UCSRA=0x00;
UCSRB=0xD8;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x19;
}
// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void){
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer[rx_wr_index]=data;
if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
if (++rx_counter == RX_BUFFER_SIZE)
{
rx_counter=0;
rx_buffer_overflow=1;
};
};
}
// USART Transmitter interrupt service routine
interrupt [USART_TXC] void usart_tx_isr(void){
if (tx_counter)
{
--tx_counter;
UDR=tx_buffer[tx_rd_index];
if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
};
}
// загрузить байт в буфер для последующей передачи
char getbyte(void){
char data;
while (rx_counter==0){}
data=rx_buffer[rx_rd_index];
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
// выгрузить из буфера байт
void putbyte(unsigned char c){
while (tx_counter == TX_BUFFER_SIZE);
#asm("cli")
if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
{
tx_buffer[tx_wr_index]=c;
if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
++tx_counter;
}
else {UDR=c;}
#asm("sei")
}
//****************************************************
//**** Команды управления контроллером MC3PHAC ********
// 3.5В(зн.АЦП=717) на выводе DC_bus принято за 100% (310В) напряжения питания инвертора
unsigned char const cmd_RESET[5] = {0xE3, 0x10, 0x00, 0x30, 0x00};
unsigned char const cmd_PPWM[5] = {0xE3, 0x10, 0x00, 0x50, 0x00};
unsigned char const cmd_DEADT[5] = {0xE3, 0x00, 0x36, 0x24, 0x00}; // 4.5 мкс мертвое время
unsigned char const cmd_ACB[5] = {0xE3, 0x10, 0x00, 0x61, 0x00}; // 50 Гц базовая частота
unsigned char const cmd_ACC[5] = {0xE4, 0x00, 0x60, 0x05, 0x00}; // 5 Гц/c ускорение
unsigned char const cmd_F[5] = {0xE4, 0x00, 0x62, 0x06, 0x80}; // 6.5 Гц задание синусоидальной частоты
unsigned char const cmd_FPWM[5] = {0xE3, 0x10, 0x00, 0x42, 0x00}; //10.6 кГц частота ШИМ
unsigned char const cmd_VBOOST[5] = {0xE3, 0x00, 0x6C, 0x00, 0x00}; // 0 % амплитуда синуса при нулевой синусоидальной частоте
unsigned char const cmd_MODIN[5] = {0xE3, 0x00, 0x75, 0xFE, 0x00}; // 99 % индекс модуляции синуса (амплитуда)
unsigned char const cmd_FTOUT[5] = {0xE4, 0x00, 0x6A, 0x00, 0x05}; // 1.3 c таймаут после аварии
unsigned char const cmd_VBDEC[5] = {0xE4, 0x00, 0xC9, 0x03, 0x55}; // 119 % значение Vbus при котором начинается снижение скорости торможения
unsigned char const cmd_VBRAKE[5] = {0xE4, 0x00, 0x64, 0x03, 0x55}; // 119 % значение Vbus при котором появляется сигнал вкл. тормозного VT
unsigned char const cmd_VBROWN[5] = {0xE4, 0x00, 0x66, 0x01, 0xF6}; // 71 % нижнее значение Vbus при откл. ШИМ и появляется сигнал аварии
unsigned char const cmd_VBOVR[5] = {0xE4, 0x00, 0x68, 0x03, 0x71}; // 123 % верхнее значение Vbus при откл. ШИМ и появляется сигнал аварии
unsigned char const cmd_FORW[5] = {0xE3, 0x10, 0x00, 0x10, 0x00}; // "вперед"
unsigned char const cmd_REW[5] = {0xE3, 0x10, 0x00, 0x11, 0x00}; // "назад"
unsigned char const cmd_STOP[5] = {0xE3, 0x10, 0x00, 0x20, 0x00}; // "стоп"
unsigned char const read_ACTF[3] = {0xD1, 0x00, 0x85}; // прочитать текущюю синусоидальную частоту
unsigned char const read_SETUP[3] = {0xD0, 0x00, 0xAE}; // прочитать регистр установок
unsigned char const read_VBUS[3] = {0xD1, 0x00, 0x79}; // прочитать напряжение питания инвертора (DC_bus)
unsigned char const read_F[3] = {0xD1, 0x00, 0x62}; // прочитать задание на синусоидальную частоту
unsigned char const read_STATUS[3] = {0xD0, 0x00, 0xC8}; // прочитать регистр статуса
//******************************************************
//***************** Процедуры **************************
// посылка команды
void MC3PHAC_Send(flash unsigned char *msg,unsigned char len){
unsigned char CRC=0;
putbyte(0x2B);
while(len>0){
if(*msg==0x2B){putbyte(0x2B);} // повторить байт
putbyte(*msg);
CRC+=*msg;
*msg++;
len--;
}
putbyte((unsigned char)(~CRC+1));
delay_ms(40);
}
// прием ответа типа Word (формат ответа: 2B_00_Hi_Lo_CRC)
unsigned int RxWord(){
unsigned char CRC,Lo,Hi;
unsigned int data=0;
getbyte(); //2B
CRC=getbyte(); //00
Hi=getbyte();CRC+=Hi; //Hi
if(Hi==0x2B){getbyte();}//пропустить байт подтверждения
Lo=getbyte();CRC+=Lo; //Lo
if(Lo==0x2B){getbyte();}//пропустить байт подтверждения
data=Hi;
data<<=8;
data+=Lo;
while((~CRC+1)!=getbyte()){} //CRC
return data;
}
// прием ответа типа Byte (формат ответа: 2B_00_Lo_CRC)
unsigned char RxByte(){
unsigned char CRC,Lo;
getbyte(); //2B
CRC=getbyte(); //00
Lo=getbyte();CRC+=Lo; //Lo
while((~CRC+1)!=getbyte()){} //CRC
return Lo;
}
// Прием ответа на команду (формат ответа: 2B_Lo_CRC)
unsigned char Response(){
unsigned char CRC,Lo;
getbyte(); //2B
Lo=getbyte(); //Lo
CRC=Lo;
while((~CRC+1)!=getbyte()){} //CRC
return Lo;
}
// идентификация MC3PHAC
void MC3PHAC_Identification(){
unsigned char i,j;
unsigned char Test_Link1[3] = {0x2B,0xC0, 0x40};
for (j=0; j<3;j++){
for (i=0;i<3;i++){
putbyte(Test_Link1[i]);
}
while(Response()!=0x81){}
}
}
// иницилизация MC3PHAC
void MC3PHAC_Init(){
MC3PHAC_Send(cmd_RESET, sizeof(cmd_RESET));
delay_ms(100);
MC3PHAC_Send(cmd_DEADT, sizeof(cmd_DEADT));
Response();
MC3PHAC_Send(cmd_PPWM, sizeof(cmd_PPWM));
Response();
MC3PHAC_Send(cmd_ACB, sizeof(cmd_ACB));
Response();
MC3PHAC_Send(cmd_ACC, sizeof(cmd_ACC));
Response();
MC3PHAC_Send(cmd_FPWM, sizeof(cmd_FPWM));
Response();
MC3PHAC_Send(cmd_F, sizeof(cmd_F));
Response();
MC3PHAC_Send(cmd_VBOOST, sizeof(cmd_FPWM));
while(Response()!=0x00){}
MC3PHAC_Send(cmd_MODIN, sizeof(cmd_MODIN));
while(Response()!=0x00){}
MC3PHAC_Send(cmd_FTOUT, sizeof(cmd_FTOUT));
while(Response()!=0x00){}
MC3PHAC_Send(cmd_VBDEC, sizeof(cmd_VBDEC));
while(Response()!=0x00){}
MC3PHAC_Send(cmd_VBRAKE, sizeof(cmd_VBRAKE));
while(Response()!=0x00){}
MC3PHAC_Send(cmd_VBROWN, sizeof(cmd_VBROWN));
while(Response()!=0x00){}
MC3PHAC_Send(cmd_VBOVR, sizeof(cmd_VBOVR));
while(Response()!=0x00){}
}
//******************************************************
Пример основной программы в которую подгружается драйвер
примечание : при отсутствии связи (ошибке ответа) прога заходит в бесконечный цикл while(1){}
#include <mega16.h>
#include <delay.h> #include <stdio.h>
//************** Глобальные переменные *************
unsigned int period,timer; unsigned int f; unsigned int zad_f; unsigned int voltage_bus; bit PUSK=0; unsigned char status; //**************************************************
#include "driver_mc3phac.h"
void init(){ PORTC=0b00000000; DDRC= 0b11111111; PORTD=0b00001000; DDRD= 0b10001000; PORTA=0b00111100; DDRA= 0b11111100; PORTB=0b00000000; DDRB= 0b00000000; // и т.д и т.п. }
void main(void){ init(); USART_init(); #asm("sei") delay_ms(1000); MC3PHAC_Identification(); MC3PHAC_Init(); MC3PHAC_Send(read_SETUP,sizeof(read_SETUP)); while(RxByte()!=0xFF){} // проверка готовности перед включением ШИМ
while (1){ MC3PHAC_Send(cmd_FORW,sizeof(cmd_FORW)); // включение двигателя вперед Response();
MC3PHAC_Send(read_ACTF,sizeof(read_ACTF)); // пример чтения текущей синусоидальной частоты f=RxWord();
}
}
|
|
|
|
|
 |
Ответов
|
Feb 27 2011, 20:31
|
Группа: Новичок
Сообщений: 9
Регистрация: 20-10-10
Пользователь №: 60 297

|
Цитата(Chip115 @ Feb 26 2011, 18:01)  Доброго времени суток! В данный момент пишу софт для контроллера C8051F410 который будет управлять таким же контроллером. Есть некоторые вопросы относительно управления MC3PHAC. Не могли бы Вы мне помочь разобраться так как чтение документации не дает всех ответов для меня . В общем случае мне надо реализовать функцию,выполняющею следующие действия : запуск на n секунд - остановка - реверс - запуск на n секунд... . и т.д. Для второго двигателя должны ввести скорость вращения ротора, а затем гонять туда - сюда. т.е запуск - стоп-реверс-запуск... Так вопросы следующие: Функция инициализации MC3PHAC должна быть такая же как и у Вас? И что значит ускорение? он будет постепенно разгоняться с определенной dw/dt или сразу после старта он выйдет на нужную скорость? инициализация должна быть такая же единственное - не обязательно выполнять идентификацию (ее я делаю для тестирования связи с MC3PHAC - можно исключить или наоборот сделать несколько раз) еще задержки могут быть другие это не так кретично, может быть другая последовательность инициализации, но самое главное в конце установки всех параметров (при инициализации) проверить регистр setup -все биты в нем должны быть установленны иначе потом пуск не пройдет. Разгоняться двигатель будет с заданным ускарением (минимальное вроде 0,5Гц /c) c нуля. при сигнале аварии мгновенно отключается ШИМ, отчитывается таймаут и автоматически начинается перезапуск (опять же с нуля и тем же ускорением). При остановке все происходит аналогично но в обратной последовательности. скорость разгона - константа. Ниже выложу ссылку на видео там видно как наростает частота (по лампочке и индикатору ) обновленный драйвер (исправленный и дополненный) CODE
//*************************************************** // Драйвер управления MC3PHAC по UART * // V2.0 15.02.2011 * //***************************************************
// CodeVisionAVR V 2.03.4 Standart
// Драйвер использует следующие аппартные // средства контроллера: UART; Timer2 // при инициализации драйвера включается глоб. прерывание // тактовая частота контроллера 4 MHz
//********************** UART ************************
#define RXB8 1 #define TXB8 0 #define UPE 2 #define OVR 3 #define FE 4 #define UDRE 5 #define RXC 7 #define FRAMING_ERROR (1<<FE) #define PARITY_ERROR (1<<UPE) #define DATA_OVERRUN (1<<OVR) #define DATA_REGISTER_EMPTY (1<<UDRE) #define RX_COMPLETE (1<<RXC) #define RX_BUFFER_SIZE 64 #define TX_BUFFER_SIZE 64 unsigned char Copy_Buffer[10],h=0; char rx_buffer[RX_BUFFER_SIZE]; char tx_buffer[TX_BUFFER_SIZE]; unsigned char tx_wr_index,tx_rd_index,tx_counter=0; unsigned char rx_wr_index=0,rx_rd_index,rx_counter=0; bit rx_buffer_overflow;
// инициализация UART void driver_init(){ UCSRA=0x00; UCSRB=0xD8; UCSRC=0x86; UBRRH=0x00; UBRRL=0x19;
// Clock source: System Clock // Clock value: 31,250 kHz // Mode: CTC top=OCR2 // OC2 output: Disconnected ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0xF0; // величина таймаута при ожидании ответа (шаг = 256 мкс) TIMSK|=0x80; // включение прерывания по таймауту (таймер 2) #asm("sei") // глобальное включение прерывания
}
// USART Receiver interrupt service routine interrupt [USART_RXC] void usart_rx_isr(void){ char status,data; status=UCSRA; data=UDR; if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) { rx_buffer[rx_wr_index]=data; if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0; if (++rx_counter == RX_BUFFER_SIZE) { rx_counter=0; rx_buffer_overflow=1; } } }
/* коды ошибок 301 - таймаут UART превышен 302 - ошибка CRC 303 - потеряно начало сообщения */
Error_UART(unsigned char N){ // аварии по интерфейсу можно исключить для упрощ. while(!BUT){ IntToDec(300+N); // я например вывожу на индикатор } delay_ms(500); }
// USART Transmitter interrupt service routine interrupt [USART_TXC] void usart_tx_isr(void){ if (tx_counter) { --tx_counter; UDR=tx_buffer[tx_rd_index]; if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0; } } // прерываниие по истечению таймаута (нет ответа от MC3PHAC) interrupt [TIM2_COMP] void timer2_comp_isr(void) {TCCR2=0x00;} // остановили таймаут
// выгрузить из буфера байт char getbyte(void){ char data; TCNT2=0x00; if (rx_counter==0){ // нет ответа TCCR2=0x0F; //вкл таймаут ожидания while(TCCR2==0x0F){ // начинаем ждать HL_REW=1; delay_ms(50); HL_REW=0; delay_ms(50); if(rx_counter>0){goto next;} } Error_UART(1); HL_FWR=1; // превышен таймаут delay_ms(200); HL_FWR=0; delay_ms(200); return 0x00; // выйти из таймаута } next: HL_REW=0; data=rx_buffer[rx_rd_index]; if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0; #asm("cli") --rx_counter; #asm("sei") return data; } // загрузить байт в буфер для последующей передачи void putbyte(unsigned char c){ while (tx_counter == TX_BUFFER_SIZE){} #asm("cli") if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0)) { tx_buffer[tx_wr_index]=c; if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0; ++tx_counter; } else {UDR=c;} #asm("sei") }
//**** Команды управления контроллером MC3PHAC ******** // 3.5В(зн.АЦП=717) на выводе DC_bus принято за 100% (310В) напряжения питания инвертора unsigned char const cmd_RESET[5] = {0xE3, 0x10, 0x00, 0x30, 0x00}; unsigned char const cmd_PPWM[5] = {0xE3, 0x10, 0x00, 0x50, 0x00}; unsigned char const cmd_DEADT[5] = {0xE3, 0x00, 0x36, 0x24, 0x00}; // 4.5 мкс мертвое время 24 unsigned char const cmd_ACB[5] = {0xE3, 0x10, 0x00, 0x61, 0x00}; // 50 Гц базовая частота unsigned char const cmd_ACC[5] = {0xE4, 0x00, 0x60, 0x05, 0x00}; // ускорение unsigned char const cmd_F[5] = {0xE4, 0x00, 0x62, 0x3C, 0x99}; // задание синусоидальной частоты unsigned char const cmd_FPWM[5] = {0xE3, 0x10, 0x00, 0x42, 0x00}; //10.6 кГц частота ШИМ unsigned char const cmd_VBOOST[5] = {0xE3, 0x00, 0x6C, 0x00, 0x00}; // 0 % амплитуда синуса при нулевой синусоидальной частоте unsigned char const cmd_MODIN[5] = {0xE3, 0x00, 0x75, 0xFE, 0x00}; // 99 % индекс модуляции синуса (амплитуда) unsigned char const cmd_FTOUT[5] = {0xE4, 0x00, 0x6A, 0x00, 0x08}; // таймаут после аварии unsigned char const cmd_VBDEC[5] = {0xE4, 0x00, 0xC9, 0x03, 0x55}; // 119 % значение Vbus при котором начинается снижение скорости торможения unsigned char const cmd_VBRAKE[5] = {0xE4, 0x00, 0x64, 0x03, 0x55}; // 119 % значение Vbus при котором появляется сигнал вкл. тормозного VT unsigned char const cmd_VBROWN[5] = {0xE4, 0x00, 0x66, 0x80, 0x00}; // 50 % нижнее значение Vbus при откл. ШИМ и появляется сигнал аварии unsigned char const cmd_VBOVR[5] = {0xE4, 0x00, 0x68, 0x03, 0x71}; // 123 % верхнее значение Vbus при откл. ШИМ и появляется сигнал аварии unsigned char const cmd_FORW[5] = {0xE3, 0x10, 0x00, 0x10, 0x00}; // "вперед" unsigned char const cmd_REW[5] = {0xE3, 0x10, 0x00, 0x11, 0x00}; // "назад" unsigned char const cmd_STOP[5] = {0xE3, 0x10, 0x00, 0x20, 0x00}; // "стоп" unsigned char const read_ACTF[3] = {0xD1, 0x00, 0x85}; // прочитать текущюю синусоидальную частоту unsigned char const read_SETUP[3] = {0xD0, 0x00, 0xAE}; // прочитать регистр установок unsigned char const read_VBUS[3] = {0xD1, 0x00, 0x79}; // прочитать напряжение питания инвертора (DC_bus) unsigned char const read_F[3] = {0xD1, 0x00, 0x62}; // прочитать задание на синусоидальную частоту unsigned char const read_STATUS[3] = {0xD0, 0x00, 0xC8}; // прочитать регистр статуса //******************************************************
//***************** Процедуры **************************
// посылка команды (любой) void MC3PHAC_Send(flash unsigned char *msg,unsigned char len){ unsigned char CRC=0;
putbyte(0x2B); while(len>0){ if(*msg==0x2B){putbyte(0x2B);} // повторить байт putbyte(*msg); CRC+=*msg; *msg++; len--; } CRC=~CRC+1; putbyte(CRC); if(CRC==0x2B){putbyte(CRC);} //delay_ms(40); // не трогать } // посылка команды на задание синусоидальной частоты void MC3PHAC_Send_F(unsigned char Hz,unsigned char Hz_Lo){ unsigned char CRC=0; putbyte(0x2B); putbyte(0xE4); putbyte(0x00); putbyte(0x62); CRC=0x46; putbyte(Hz);CRC+=Hz; if(Hz==0x2B){putbyte(0x2B);} // повторить байт putbyte(Hz_Lo);CRC+=Hz_Lo; if(Hz_Lo==0x2B){putbyte(0x2B);} // повторить байт putbyte((unsigned char)(~CRC+1)); } // прием ответа типа Word (формат ответа: 2B_00_Hi_Lo_CRC) unsigned int RxWord(){ unsigned char CRC,Lo,Hi; unsigned int data=0; if(getbyte()!=0x2B){Error_UART(3);}; //2B CRC=getbyte(); //00 Hi=getbyte();CRC+=Hi; //Hi if(Hi==0x2B){getbyte();} //пропустить байт подтверждения Lo=getbyte();CRC+=Lo; //Lo if(Lo==0x2B){getbyte();} //пропустить байт подтверждения data=Hi; data<<=8; data+=Lo; Lo=getbyte(); if(Lo==0x2B){getbyte();} //пропустить байт подтверждения if((~CRC+1)!=Lo){Error_UART(2);} //проверка CRC return data; } // прием ответа типа Byte (формат ответа: 2B_00_Lo_CRC) unsigned char RxByte(){ unsigned char CRC,Lo; getbyte(); //2B CRC=getbyte(); //00 Lo=getbyte();CRC+=Lo; //Lo if((~CRC+1)!=getbyte()){Error_UART(2);} //проверка CRC return Lo; } // Прием ответа на команду (формат ответа: 2B_Lo_CRC) unsigned char Response(){ unsigned char CRC,Lo; getbyte(); //2B Lo=getbyte(); //Lo CRC=Lo; if((~CRC+1)!=getbyte()){Error_UART(2);} //проверка CRC return Lo; } // идентификация MC3PHAC void MC3PHAC_Identification(){ unsigned char i,j; unsigned char Test_Link1[3] = {0x2B,0xC0, 0x40}; for (j=0; j<3;j++){ for (i=0;i<3;i++){ putbyte(Test_Link1[i]); } if(Response()!=0x81){Error_UART(2);} } } // иницилизация MC3PHAC void MC3PHAC_Init(){ MC3PHAC_Send(cmd_RESET, sizeof(cmd_RESET)); delay_ms(100); MC3PHAC_Send(cmd_DEADT, sizeof(cmd_DEADT)); Response(); MC3PHAC_Send(cmd_PPWM, sizeof(cmd_PPWM)); Response(); MC3PHAC_Send(cmd_ACB, sizeof(cmd_ACB)); Response(); MC3PHAC_Send(cmd_ACC, sizeof(cmd_ACC)); Response(); MC3PHAC_Send(cmd_FPWM, sizeof(cmd_FPWM)); Response(); MC3PHAC_Send(cmd_F, sizeof(cmd_F)); Response(); MC3PHAC_Send(cmd_VBOOST, sizeof(cmd_FPWM)); Response(); MC3PHAC_Send(cmd_MODIN, sizeof(cmd_MODIN)); Response(); MC3PHAC_Send(cmd_FTOUT, sizeof(cmd_FTOUT)); Response(); MC3PHAC_Send(cmd_VBDEC, sizeof(cmd_VBDEC)); Response(); MC3PHAC_Send(cmd_VBRAKE, sizeof(cmd_VBRAKE)); Response(); MC3PHAC_Send(cmd_VBROWN, sizeof(cmd_VBROWN)); Response(); MC3PHAC_Send(cmd_VBOVR, sizeof(cmd_VBOVR)); Response(); }
и пример самой программы (как вариант) CODE
#include <mega16.h> #include <delay.h> #include <stdio.h>
#define OK4 PORTA.3 // Общий катод индикатора
#define OK3 PORTA.2 // Общий катод индикатора
#define OK2 PORTA.4 // Общий катод индикатора
#define OK1 PORTA.5 // Общий катод индикатора
#define HL_FWR PORTA.6 // Светодиод "Вперед"
#define HL_REW PORTA.7 // Светодиод "Назад"
#define ALARM PORTD.7 // Выход аварии
#define Blok_DR PORTD.3 // Выход блокировки драйвера
#define BUT PIND.5 // Вход кнопки
#define TEST 0 //Режимы работы
#define NORM 1 //Режимы работы
#define ADC_VREF_TYPE 0xC0
/*
внеш торм транз. вкл при 365В
100%=310B (3.5В)
*/
//************** Глобальные переменные *************
unsigned char DigSot,DigDec,DigEd;
unsigned char MaskaDig[11]={63,48,91,121,116,109,111,56,127,125,1};
float gl_var_dig_f=0;
unsigned char regim;
unsigned int period,timer;
unsigned int F; // текущая синусоидальная частота ШИМ
unsigned int Zad_F;
unsigned int voltage_bus;
bit PUSK=0;
unsigned char status;
//**************************************************
void IntToDec(unsigned int data){ //
unsigned char _digdec=0,_digsot=0;
while (data>=100){data-=100;_digsot++;}
while (data>=10){data-=10;_digdec++;}
DigEd=data;
DigDec=_digdec;
DigSot=_digsot;
}
#include "driver_mc3phac.h"
// прерывание динамической индикации
interrupt [TIM0_COMP] void timer0_comp_isr(void){// дин инд
if(OK1==0){OK1=1;OK2=0;PORTC=MaskaDig[DigSot];goto end;}
if(OK2==0){OK2=1;OK3=0;PORTC=MaskaDig[DigDec];goto end;}
if(OK3==0){OK3=1;OK4=0;PORTC=MaskaDig[DigEd];goto end;}
if(OK4==0){OK4=1;OK1=0;if(F==0){PORTC=MaskaDig[10];}else{PORTC=0;}}
end:
}
// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
ALARM=1;delay_us(1);ALARM=0; // установка аварии
}
// проверка связи
void TestSeti(){
unsigned char i,j;
unsigned char Test_Link1[3] = {0x2B,0xC0, 0x40};
for (j=0; j<10;j++){
for (i=0;i<3;i++){putbyte(Test_Link1[i]);}
Response();
}
delay_ms(100);
for (j=0; j<10;j++){
for (i=0;i<3;i++){putbyte(Test_Link1[i]);}
Response();
}
delay_ms(100);
for (j=0; j<10;j++){
for (i=0;i<3;i++){putbyte(Test_Link1[i]);}
Response();
}
HL_REW=1;HL_FWR=1;delay_ms(500);HL_REW=0;HL_FWR=0;
}
// Read the AD conversion result
unsigned int read_zad_f(){
ADMUX=0x01 | (ADC_VREF_TYPE & 0xff);
delay_us(10);
ADCSRA|=0x40;
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW ;
}
void init(){
PORTC=0b00000000;
DDRC= 0b11111111;
PORTD=0b00000000;
DDRD= 0b10000000;
PORTA=0b00111100;
DDRA= 0b11111100;
PORTB=0b00000000;
DDRB= 0b00000000;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 15,625 kHz
// Mode: CTC top=OCR0
// OC0 output: Disconnected
TCCR0=0x0C;
TCNT0=0x00;
OCR0=0x4E;
GICR|=0x80;
MCUCR=0x08;
MCUCSR=0x00;
GIFR=0x80;
ACSR=0x80;
SFIOR=0x00;
TIMSK|=0x02;
OK2=0;
// Analog Comparator initialization
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC Clock frequency: 500,000 kHz
// ADC Voltage Reference: Int., cap. on AREF
// ADC Auto Trigger Source: None
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x83;
}
unsigned int digital_filtr(unsigned int input){ // для более плавного задания на частоту (необязат)
// используется глоб переменная float gl_var_dig_f=0 - накопление
float delta; // отклонение от предыдущего измерения
delta=(float)input-gl_var_dig_f;
if((delta>2)||(delta<-2)){delta/=2;goto jump;}
//if((delta>4)||(delta<-4)){delta/=20;goto jump;}
//if((delta>2)||(delta<-2)){delta/=100;goto jump;}
delta/=20;
jump:
gl_var_dig_f=gl_var_dig_f+delta;
return gl_var_dig_f;
}
void main(void){
init();
driver_init();
HL_REW=0;
HL_FWR=0;
delay_ms(1000);
TestSeti();
MC3PHAC_Identification();
MC3PHAC_Init();
MC3PHAC_Send(read_SETUP,sizeof(read_SETUP));
while(RxByte()!=0xFF){} // проверка готовности перед включением ШИМ
regim=PINB&0b00001111; // определение режима работы
delay_ms(2000);
//***** тестовый режим******
test_reg:
if(regim!=TEST){goto norm_reg;}
MC3PHAC_Send(cmd_FORW,sizeof(cmd_FORW));
Response();
while(1){
MC3PHAC_Send(read_VBUS,sizeof(read_VBUS));
voltage_bus=RxWord();
voltage_bus=voltage_bus/2.312;
IntToDec(voltage_bus); //
delay_ms(100);
}
//***** нормальный режим******
norm_reg:
if (regim!=NORM){goto test_reg;}
while(1){ // цикл ожидания включения
Zad_F=digital_filtr(read_zad_f()>>4); // чтение задания на скорость
MC3PHAC_Send(read_ACTF,sizeof(read_ACTF)); // чтение текущей синусоидальной частоты
F=RxWord()>>8;
if(F>0){IntToDec(F);} // отображение текущей синусоидальной частоты}
else{IntToDec(Zad_F);} // отображение задания на скорость
//delay_ms(200);
if(BUT){
if(PUSK){PUSK=0;delay_ms(1000);
MC3PHAC_Send(cmd_STOP,sizeof(cmd_STOP)); // стоп двигателя
Response();HL_FWR=0;HL_REW=0;
}
else{PUSK=1;delay_ms(1000);
MC3PHAC_Send_F(Zad_F,0); // задание синусоидальной частоты
Response();
MC3PHAC_Send(cmd_FORW,sizeof(cmd_FORW)); // включение двигателя вперед
Response();HL_FWR=1;
}
}
}
goto test_reg;
}
ссылка на видео http://www.youtube.com/watch?v=J8B4RegJsdg показан разгон и торможения двигателя (вместо него лампочка). Предварительно потонцеометром (на AVR) устанапливается задание на синусоидальную частоту. Потом происходит пуск кнопкой (на AVR). Разгон длиться до заданной частоты. Потом остановка. схема для связи MC3PHAC c Atmega16 (формат P-Cad)
Сообщение отредактировал a-6539x - Feb 27 2011, 20:14
|
|
|
|
Сообщений в этой теме
a-6539x MC3PHAC+AVR Jan 30 2011, 09:38 _Pasha Сделайте в своем сообщении так: весь код заключите... Jan 30 2011, 15:09 a-6539x Цитата(_Pasha @ Jan 30 2011, 18:09) Сдела... Jan 30 2011, 19:48  Chip115 Цитата(a-6539x @ Feb 28 2011, 03:31)... Apr 12 2011, 06:23 Chip115 Спасибо за такой полный ответ!
А если без ... Mar 18 2011, 19:52 a-6539x Цитата(Chip115 @ Mar 18 2011, 22:52) Спас... Mar 23 2011, 05:28 a-6539x скорей всего это из-за ошибки в комментарии строки... Apr 18 2011, 17:22 _Pasha Цитата(a-6539x @ Apr 18 2011, 20:22)... Apr 18 2011, 18:24 MasterWizard Доброе время. Сломал себе мозг и разочаровался в с... Oct 7 2012, 13:03 _Pasha Цитата(MasterWizard @ Oct 7 2012, 16:03) ... Oct 7 2012, 14:21  MasterWizard Цитата(_Pasha @ Oct 7 2012, 18:21) У меня... Oct 7 2012, 14:38   _Pasha Цитата(MasterWizard @ Oct 7 2012, 17:38) ... Oct 7 2012, 15:46    MasterWizard Цитата(_Pasha @ Oct 7 2012, 19:46) Перепу... Oct 7 2012, 21:40     _Pasha Цитата(MasterWizard @ Oct 8 2012, 00:40) ... Oct 8 2012, 04:29      MasterWizard Цитата(_Pasha @ Oct 8 2012, 08:29) Начну ... Oct 8 2012, 05:39       _Pasha Цитата(MasterWizard @ Oct 8 2012, 08:39) ... Oct 8 2012, 08:19 MasterWizard Все страньше и страньше. Прокинул аналоговую землю... Oct 10 2012, 07:23 Agent 007 Всем привет.
У меня противоположная проблема. Ника... Mar 21 2013, 21:42
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|