You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			141 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
			
		
		
	
	
			141 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
| #include <avr/io.h>
 | |
| #include <util/delay.h>
 | |
| #include <avr/interrupt.h>
 | |
| 
 | |
| #include "modbus.h"
 | |
| #include "pid.h"
 | |
| #include "adc.h"
 | |
| #include "i2cmaster.h"
 | |
| 
 | |
| void modbusGet(void);
 | |
| 
 | |
| volatile uint16_t holdingRegisters[40];
 | |
| 
 | |
| volatile float output;
 | |
| volatile struct pid controller;
 | |
| 
 | |
| volatile float setpoint_1 = 130; 
 | |
| volatile float setpoint_2 = 150;
 | |
| volatile float setpoint_3 = 150;
 | |
| 
 | |
| int main(){
 | |
|     DDRD |= (1 << 4); // LED
 | |
|     DDRD |= (1 << 3); // FU PWM
 | |
|     DDRD |= (1 << 2); // 485 DE
 | |
| 
 | |
|     PORTD |= 1 << 4;
 | |
| 
 | |
|     DDRB |= 0x0F; // out channels
 | |
| 
 | |
| 	PORTD|=(1<<0); // RX
 | |
| 
 | |
|     // FU PWM on PD3
 | |
|     TCCR2A |= (1 << COM2B1) | (1 << COM2B0);
 | |
|     TCCR2A |= (1 << WGM21) | (1 << WGM20);
 | |
|     TCCR2B |= (1 << CS21);
 | |
| 
 | |
| 	modbusSetAddress(1);
 | |
|     modbusInit();
 | |
| 
 | |
|     // Modbus Tick Timer
 | |
|     TCCR0B|=(1<<CS01); //prescaler 8
 | |
| 	TIMSK0|=(1<<TOIE0);
 | |
| 
 | |
|     initADC();
 | |
|     i2c_init();
 | |
|     sei();
 | |
| 
 | |
|     _delay_ms(1000);
 | |
|     PORTD &= ~(1 << 4);
 | |
|     init_pid(&controller, 5, 0.2, 0);
 | |
| 
 | |
|     // timer for regler
 | |
|     TCCR1B|=(1<<CS12) | (1<<CS10);
 | |
| 	TIMSK1|=(1<<TOIE1)|(1<<OCIE1A);
 | |
| 
 | |
|     while(1){
 | |
| 	    modbusGet();
 | |
|     }
 | |
| }
 | |
| 
 | |
| void modbusGet(void) {
 | |
| 	if (modbusGetBusState() & (1<<ReceiveCompleted))
 | |
| 	{
 | |
| 		switch(rxbuffer[1]) {
 | |
|             case fcReadHoldingRegisters:
 | |
| 				modbusExchangeRegisters(holdingRegisters,0,40);
 | |
|                 break;
 | |
|             case fcPresetSingleRegister:
 | |
| 			case fcPresetMultipleRegisters: 
 | |
| 				if(modbusRequestedAmount()==1) {
 | |
|                     modbusExchangeRegisters(holdingRegisters,0,40);
 | |
|                     if(modbusIsInRange(0))
 | |
|                         /* analog out for Motor VFD */
 | |
|                         OCR2B = holdingRegisters[0] & 0xFF;
 | |
|                     if(modbusIsInRange(1)){
 | |
|                         /* i2c scanner */
 | |
|                         for(int i = 0x0; i < 0xFF; i++){
 | |
|                             if(!i2c_start(i)){
 | |
|                                 holdingRegisters[1] = i;
 | |
|                                 i2c_stop();
 | |
|                                 break;
 | |
|                             }
 | |
|                             i2c_stop();
 | |
|                         }
 | |
|                     }
 | |
|                 } else {
 | |
| 					modbusSendException(ecIllegalDataValue);
 | |
| 				}
 | |
|                 break;
 | |
|             case fcReadCoilStatus:
 | |
|             case fcForceSingleCoil:
 | |
|             case fcForceMultipleCoils:
 | |
| 				modbusExchangeBits(&PORTB,0,4);
 | |
|                 break;
 | |
| 
 | |
|             case fcReadInputRegisters:
 | |
|                 if(modbusRequestedAddress()<10)
 | |
|                     modbusExchangeRegisters((uint16_t *)&adc_avrg,0,8);
 | |
|                 else
 | |
|                     modbusExchangeRegisters((uint16_t *)&output,10,4);
 | |
|                 break;
 | |
| 			
 | |
|             default:
 | |
| 				modbusSendException(ecIllegalFunction);
 | |
|                 break;
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| ISR(TIMER0_OVF_vect) { //this ISR is called 9765.625 times per second
 | |
| 	modbusTickTimer();
 | |
| }
 | |
| 
 | |
| /* Heater PID control */
 | |
| ISR(TIMER1_OVF_vect) {
 | |
|     //output = pid_step(&controller, 1, setpoint_1 - adc_avrg[1]);
 | |
|     output = 1;
 | |
| 
 | |
|     //PORTD &= ~(1 << 4);
 | |
| 
 | |
|     if(output > 128)
 | |
|         output = 128;
 | |
| 
 | |
|     if(output >= 1){
 | |
|         uint32_t tmp = output * 512;
 | |
|         if(tmp >= 0x10000)
 | |
|             tmp = 0xFFFE;
 | |
| 
 | |
|         OCR1A = tmp;
 | |
|         PORTB |= 0x0F;
 | |
|     }
 | |
|     else
 | |
|         OCR1A = 1000;
 | |
| }
 | |
| 
 | |
| ISR(TIMER1_COMPA_vect) {
 | |
|     /* turn off outputs */
 | |
|     PORTB &= ~(0x0F);
 | |
| }
 | |
| 
 |