Сообщение от petrd:
ИМХО. Поиски черной кошки в темной комнате, которой к тому же в ней нет.
1. Устройство от чего питается? PICKit2 может отдавать не больше 25 мА.
2. Смотрите, что Вы там накодили.
1. Пробовал от компьютерного БП - эффект тот, же.
2. Мой код:
// Контроллер: PIC16F877A, датчик t: DS18B20, LCD: 16х2 с контроллером HD44780, Bipolar Step-motor
// Среда программирования: MikroC PRO for PIC v.4.60.0.0
// Автоматическое управление воздушной заслонкой бензинового генератора...
// при запуске анализируется текущая t, если она < уставки (SetTemp), то закрываем заслонку
// иначе открываем воздушную заслонку (регулируется кол-вом полных оборотов ротора и
// равна константе KolOborotov.
// Автор: я
// Дата: 16_02_2011г.
// Версия: 1.0.0
// Определение констант
// //Разрешение DS18B20 //Смещение t в C
const unsigned short TEMP_RESOLUTION = 12, OFFSET = 2;
const unsigned short FaseMax=4; // кол-во табличных значений для Step_Motor
//const unsigned int KolOborotov=FaseMax*100;// кол-во оборотов двигателя до момента полного открытия заслонки
// Определение переменных
// кол-во оборотов двигателя до момента полного открытия заслонки
unsigned int KolOborotov, CurOborotov;
unsigned short SetTemp, old_SetTemp;
unsigned short counter, curFase;
bit state, RotateForOpen;
signed short int intMinus;
char *text = "000";
char *set = "000"; // НЕ УДАЛЯТЬ! появится 4-ый знак 0 в уставки если убрать.
char *ust = "000";
unsigned temp;
// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections
// подпрограмма обработки прерывания
void interrupt(){
if(INTCON.T0IF){
switch (RotateForOpen){
case 1: { // вращение влево
curFase++; // меняем последовательность включения обмоток двигателя
if (curFase>FaseMax)
{curFase=1;} // задействуем первую обмотку двигателя
};break;// end case
case 0: { // вращение вправо
curFase--; // меняем последовательность включения обмоток двигателя
if (curFase<1)
{curFase=4;} // задействуем последнюю обмотку двигателя
};break;
}// end switch
CurOborotov++; // кол-во оборотов, совершенных ротором
INTCON.T0IF=0;
}// end INTCON.T0IF
}// end interrupt
// Процедура вращения двигателя,
// если Open=0 - закрываем заслонку
// если Open=1 - открываем заслонку
void RotateMotor(unsigned short int Open){
CurOborotov=0; // текущие обороты ротора
RotateForOpen=Open; // задаем направление для вращения ротора Step-motor// задаем вращение
if (Open){curFase=4;}else{curFase=1;}
// ОТКРЫВАЕМ ИЛИ ЗАКРЫВАЕМ ЗАСЛОНКУ
while (CurOborotov<KolOborotov){
switch (curFase){
case 1: {PORTC=0b00001001;};break; //17&18 pins PIC16F877A
case 2: {PORTC=0b00000101;};break; //
case 3: {PORTC=0b00000110;};break;
case 4: {PORTC=0b00001010;};break;
}// end switch
// RA4_bit=0 - кнопка нажата, RA4_bit=1 - кнопка отпущена
// Если при закрывании заслонки была нажата кнопка, то останавливаем двигатель
if (!RA4_bit&!Open){
Eeprom_Write(0x0F,CurOborotov); // запоминаем кол-во оборотов ротора до нажатия кнопки
delay_ms(50);
CurOborotov=KolOborotov;
} // останавливаем ротор!
}// end while
PORTC=0; // Снимаем напряжение с двигателя!!!
}// end RotateMotor
void Display_Temperature(unsigned int temp2write) {
const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
char temp_whole;
unsigned int temp_fraction;
// преобразование отрицательной температуры
if (temp2write & 0x8000) {
intMinus=-1;
Lcd_Chr(1,3,'-');
temp2write = ~temp2write + 1;
}
else{
intMinus=1;
Lcd_Chr(1,3,' ');}
// извлечение целой части
temp_whole = temp2write >> RES_SHIFT ;
// преобразование целой части температуры в символы
text[0] = temp_whole/100 + 48; // извлечение сотен
text[1] = (temp_whole/10)%10 + 48; // извлечение десятков
text[2] = temp_whole%10 + 48; // извлечение единиц
// извлечение и преобразование дробной части
temp_fraction = temp2write << (4-RES_SHIFT);
temp_fraction &= 0x000F;
temp_fraction *= 625;
// преобразование дробной части в символы
text[4] = temp_fraction/1000 + 48; // extract thousands digit
text[5] = (temp_fraction/100)%10 + 48; // extract hundreds digit
text[6] = (temp_fraction/10)%10 + 48; // extract tens digit
text[7] = temp_fraction%10 + 48; // extract ones digit
// вывод температуры на ЖКИ
Lcd_Out(1, 4, text);
//Вывод уставки на ЖКИ
ust[0]=SetTemp/100+48;
ust[1]=(SetTemp/10)%10+48;
ust[2]=SetTemp%10+48;
// обрезаем дробную часть уставки
ust[3]=0;
ust[4]=0;
Lcd_Out(1,12,ust);
//if (RA3_bit){Lcd_Out(2, 10, "CLOSE");}else{Lcd_Out(2, 10, "OPEN ");}//08_11_2011
if (!RA4_bit){Lcd_Out(2, 10, "CLOSE");}else{Lcd_Out(2, 10, "OPEN ");}
intMinus*=temp_whole;
switch (state){
case 0:{
// если уставка выше
if (SetTemp>intMinus){PORTA=8;}// то включение
else{ // если нет
PORTA=0; // выключение
state=1;
}
};break;
case 1:{
// если уставка выше
if (SetTemp-OFFSET>intMinus){
PORTA=8; // то включение
state=0;}
else{PORTA=0;} // выключение
};break;
}// end switch (state)
}// end Display_Temperature
void Init(){
delay_ms(1); // задержка перед выполнением программы! --Не убирать! Нужно подбирать если программа не запускается!
ADCON1=6;
TRISA=0b11110111;
TRISC=0;
PORTC=0; // двигатель СТОП!
//OPTION_REG = 0x87; // настройка TMR0, прерывания будут каждые 66,304 ms - в HEX
OPTION_REG = 0b10000111; // настройка TMR0, прерывания будут каждые 66,304 ms - в Binary
INTCON.T0IE=1; // разрешили прерывания по переполнению TMR0
INTCON.GIE=1; // разрешили все прерывания
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Очистить дисплей
Lcd_Cmd(_LCD_CURSOR_OFF); // Курсор не отображать
Lcd_Out(1, 1, "t="); // вывод t=
Lcd_Out(1,8,"C;u="); // вывод C;u=
Lcd_Chr(1,7,223); // вывод символа точки и "С" как единицы измеренияLcd_Chr(1,16,'C');
Lcd_Chr(1,15,223); // вывод символа точки и "С" как единицы измеренияLcd_Chr(1,16,'C');
Lcd_Chr(1,16,'C'); // вывод С
Lcd_Out(2, 1, "DUMPER = "); // вывод DUMPER =
SetTemp=Eeprom_Read(0); // читаем уставку из EEPROM
delay_ms(50);
if (SetTemp>125){
SetTemp=25;
old_SetTemp=SetTemp;
Eeprom_Write(0,SetTemp); // если больше 125 градусов сохраняем в EEPROM t=25C
delay_ms(50);
} //end if (SetTemp>125)
} // end Init()
void main() {
unsigned short iDO, KolClose, KolOpen;
Init(); // Инициализируем LCD и читаем уставку
KolOborotov=Eeprom_Read(0x0F);// читаем кол-во оборотов ротора из EEPROM
delay_ms(50);
if (KolOborotov < 10){
KolOborotov=FaseMax*100;
Eeprom_Write(0x0F,KolOborotov);
delay_ms(50);
}
iDO=0; // счетчик, играет роль задержки для измерения t, а потом уже двигаем заслонку
KolClose=1; // разрешаем закрытие заслонки только один раз (если не сработает кнопка)
KolOpen=1; // разрешаем открытие заслонки только один раз (если не сработает кнопка)
//--- главный цикл
do {
//--- чтение температуры из DS18B20
Ow_Reset(&PORTA,2); // сигнал сброса
Ow_Write(&PORTA,2,0xCC); // команда SKIP_ROM
Ow_Write(&PORTA,2,0x44); // команда CONVERT_T
Delay_us(120);
Ow_Reset(&PORTA,2);
Ow_Write(&PORTA,2,0xCC); // команда SKIP_ROM
Ow_Write(&PORTA,2,0xBE); // команда READ_SCRATCHPAD
temp = Ow_Read(&PORTA,2);
temp = (Ow_Read(&PORTA,2) << 8) + temp;
//--- чтение температуры из DS18B20
if (Button(&PORTA, 0,1,0)){ // нажимаем кнопку на RA0 ("уставка выше")
SetTemp++;
if (SetTemp>125){SetTemp=125;}}
if (Button(&PORTA, 1,1,0)){ // нажимаем кнопку на RA1 ("уставка ниже")
SetTemp-- ;
if (setTemp==255){SetTemp=0;}}
if (old_SetTemp!= SetTemp) { // если было изменение уставки
Eeprom_Write(0,SetTemp); // то сохраняем в EEPROM новое значение уставки
delay_ms(50);
old_SetTemp = SetTemp; // и сохраняем для текущей работы
}
//--- форматирование, вывод на ЖКИ температуры и уставки, включение-выключение
Display_Temperature(temp);
Delay_ms(500);
//RA3_bit=0, если измеренная t>t уставки
//RA3_bit=1, если измеренная t<t уставки
//RA4_bit=0, если заслонка закрыта (кнопка замкнута на массу)
//RA4_bit=1, если заслонка открыта (кнопка отпущена - высокий уровень)
iDO++;
if (iDO>2){
if (!RA3_bit&!RA4_bit&KolOpen<2){
RotateMotor(1); // открываем заслонку
KolClose=1; // разрешаем закрыть заслонку, т.к. она 100% открыта
KolOpen=2;
}// end if
// Ввели переменную
else if (RA3_bit&RA4_bit&KolClose<2){
RotateMotor(0); // закрываем заслонку
KolClose=2; // если вдруг кнопка не замкнулась на массу, то чтобы двигатель
KolOpen=1;
}// end else if // не пытался бесконечно это делать - останавливаем его
iDO=5;}// end if iDO
}// end do
while(1);
}// end main
[Ответ]