Sida 1 av 1

Proggar 16U4

Postat: 27 oktober 2013, 14:42:58
av 1802

Kod: Markera allt

/*
 * PB012PE6.c Blinka PB0 PB1 PB2 3fas  PE6 indikerar
 * PF4 - PF7 Pottar styr tempo m.m
 * Created: 2013-10-26 20:02:53
 */ 

#include <avr/interrupt.h>
#include <avr/power.h>
#include <avr/wdt.h>
#include <avr/io.h>
#include <util/delay.h>

volatile unsigned char timer10ms = 0;
volatile unsigned char timer1s = 0;

// Configures the board hardware and chip peripherals for the demo's functionality. 
void SetupHardware(void)
{
	// Disable watchdog if enabled by bootloader/fuses 
	MCUSR &= ~(1 << WDRF);
	wdt_disable();
	
	clock_prescale_set(clock_div_1);// Disable clock division 
	
	DDRB = 0xFF;					// Output
	DDRC = 0xC0;					// Output
	DDRD = 0xFF;					// Output
	DDRE = (1<<PE6);				// LED port as output
	DDRF = 0xF3;					// Output (ändra till analog input)

	// Init timer 0, Compare Match A
	TCCR0A = (1<<WGM01);			// CTC (Clear timer on compare match)
	TCCR0B = (1<<CS02) | (1<<CS00);	// Clock/1024
	OCR0A = 78;						// Around 10ms
	TIMSK0 = (1<<OCIE0A);			// Interrupt enable
}


int main(void)
{
	// Disable JTAG
	MCUCR = (1<<JTD);
	MCUCR = (1<<JTD); 
	
	SetupHardware();
	
	sei();							// Enable global interrupt

int d = 4000;

	for (;;)
	{		
	//	if(timer1s)
		{
			PORTE &= ~(1 << PE6);   // PE6 
			PORTB &= ~(1 << PB2);   // PB2 off
			PORTB |= (1 << PB0);  // PB0 on  LED1
			 _delay_ms (d);			
			PORTE |= (1 << PE6);  // PE6 
			PORTB &= ~(1 << PB0);   // PB0 off
			PORTB |= (1 << PB1);  // PB1 on  LED2
			 _delay_ms(d);
			PORTE &= ~(1 << PE6);   // PE6 
			PORTB &= ~(1 << PB1);   // PB1 off
			PORTB |= (1 << PB2);  // PB2 on  LED3
			 _delay_ms(d);
//			PORTE &= ~(1 << PE6);   // PE6 
//			PORTB &= ~(1 << PB2);   // PB2 off  
//			 _delay_ms(10000);			 
//			timer1s = 0;
		}
	}
}



// Timer 0 CTC ISR, firing every 10 millisecond to keep track of time. 
ISR(TIMER0_COMPA_vect)
{
	timer10ms++;
	if(timer10ms >= 100){
		timer10ms = 0;		
		timer1s = 1;
	}
}
Högnivåspråk? Varför inte skriva NAND OR istället för kryptiska tecken? Har inte provat om det går. Skall nog ändra till "PORTE ^= (1<<PE6);" så den togglar. PE6 är den inbyggda, så den gör nått när kortet jobbar fristående. Skall försöka kombinera med nedan högnivårutin(not).

Kod: Markera allt

/* Simple example for Teensy USB Development Board
 * http://www.pjrc.com/teensy/
 * Copyright (c) 2008 PJRC.COM, LLC
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include <stdint.h>
#include <stdlib.h>
#include <util/delay.h>
#include "usb_serial.h"

#define LED_CONFIG	(DDRE |= (1<<6))
#define LED_ON		(PORTE &= ~(1<<6))
#define LED_OFF		(PORTE |= (1<<6))
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
enum ADC_ref{ AVCC_REF, INTERNAL_REF };

void send_pstr(const char *s);
void send_str(int8_t *s);
uint16_t analog_read_ADC(uint8_t channel, uint8_t ADC_ref);


// Very simple character echo test
int main(void)
{
	// Disable JTAG
	MCUCR = (1<<JTD);
	MCUCR = (1<<JTD);

	// Disable watchdog if enabled by bootloader/fuses 
	MCUSR &= ~(1 << WDRF);
	wdt_disable();
	 
	CPU_PRESCALE(0);
	LED_CONFIG;
	LED_ON;
	usb_init();
	while (!usb_configured()) /* wait */ ;
	_delay_ms(1000);

	// Discard anything that was received prior.  Sometimes the
	// operating system or other software will send a modem
	// "AT command", which can still be buffered.
	usb_serial_flush_input();
	LED_OFF;
	//send_str(PSTR("Simple-USB is ready to use!\r\n"));
	
	while (1) 
	{
		if(!(PINE & 0x04))		// HWB=0 ?
		{			
			send_pstr(PSTR("Button is pressed\r\n"));
			uint16_t ADC_result = 0;
			int8_t tmpBuf[6];
			// Read ADC channel 0, 1, 4, 5, 6 and 7 located on PORT F
			for(unsigned char i=0; i<8; i++)
			{
				if(i==2)
					i += 2;					

				ADC_result = analog_read_ADC(i, INTERNAL_REF);
				ADC_result = (ADC_result*25)/10;		// Convert to mV
				itoa(ADC_result, (char*)tmpBuf, 10);
				send_str(tmpBuf);
				usb_serial_putchar(';');
			}
			send_pstr(PSTR("\r\n"));
			_delay_ms(10);
		}
		
		int n = usb_serial_getchar();
		if (n >= 0) 
		{
			usb_serial_putchar(n);
			LED_ON;
			_delay_ms(1);
			LED_OFF;
		}
	}
}


// Send a string to the USB serial port.  The string must be in
// flash memory, using PSTR
//
void send_pstr(const char *s)
{
	char c;
	while (1) 
	{
		c = pgm_read_byte(s++);
		if (!c) break;
		usb_serial_putchar(c);
	}
}

// Send a string to the USB serial port.  
//
void send_str(int8_t *s)
{
	while (*s) 
	{
		usb_serial_putchar(*s);
		s++;
	}
}


/**
 * @brief Read a ADC channel in the Atmega
 *
 * @param channel	The channel to be read
 * @param ADC_ref	The ADC reference to be used
 *
 * @return 10 bit ADC value
 */
uint16_t analog_read_ADC(uint8_t channel, uint8_t ADC_ref)
{
#define NUMBER_OF_SAMPLES 2

	uint16_t AD_value = 0;
	uint16_t uiTemp = 0;
	uint8_t i = 0;
	
	if(ADC_ref == AVCC_REF){
		ADMUX = (1<<REFS0) | channel;				// AVCC reference + channel select 
	}
	else if(ADC_ref == INTERNAL_REF){
		ADMUX = (1<<REFS1) | (1<<REFS0) | channel;	// Internal 2,56 volt reference + channel select
	}

	// ADC enable and start conversion, division factor = 64 (125 kHz at 8 MHz)
	
	// Enable ADC and make a reading, first reading may be wrong so we don't save it
	ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADPS1) | (1<<ADPS2);	
	while (ADCSRA & (1<<ADSC));						// Wait for conversion to be finish
	_delay_us(200);									// Let the Aref capacitor charge	
	
	for(i=0; i<NUMBER_OF_SAMPLES; i++)				// We do some samples
	{
		ADCSRA = (1<<ADEN) | (1<<ADSC) | (1<<ADPS1) | (1<<ADPS2);	

		while (ADCSRA & (1<<ADSC));					// Wait for conversion to be finish

		uiTemp = ADCL;								// Important, read ADCL first
		uiTemp += (ADCH << 8);
		AD_value += uiTemp;
	}
	AD_value /= NUMBER_OF_SAMPLES;					// Divide by number of samples

	ADMUX = 0x00;									// Shutdown ADC to save power
	ADCSRA = 0x00;

	return AD_value;
}

Går det att använda ArduinoIDE till 16U4? Lättare med tex analogread mfl. Tex Arduino Leonardo har 32U4, nästan samma. Jag proggar min 16U4 med Flip, så det räcker med en fungerande hexfil. Hur funkar det i ArduinoIDE när man skall konvertera arduino uno progg till Leonardo? Fixar den att benen heter olika automagiskt?