# Leer estado del puerto avr con C Pequeño detalle Atmega



## R-Mario (Feb 28, 2011)

Ok gracias por tomarse el tiempo de leer esto yo tengo una cuestion como le hago para leer el estado de un solo pin del puerto X en los avr, yo para cambiar el estado de los pines de salida le hago asi

PORTA |= (1<<PA0)   Activo el pin 0 del puerto A sin afectar a los demas
PORTA ^= (1<<PA0) Desactivo el pin 0 del puerto A sin afectar a los demas

Y para leerlos cual seria la mejor forma, segun lo de arriba es la mejor forma para los pines de salida pero que hay para los de la entrada 

if(PINA&PD0){ } Si es uno 
if(!(PINA&PD0)){} Si es cero

Esto podria funcionar o que utilizan ustedes para esto claro menos ensamblador, por cierto me gustaria que fueran poniendo detalles que ustedes utilizan para facilitarse la programacion en C para AVR, detalles pequeños como este pero que son de utilidad


----------



## dukex (Mar 1, 2011)

Benito2312 dijo:


> Ok gracias por tomarse el tiempo de leer esto yo tengo una cuestion como le hago para leer el estado de un solo pin del puerto X en los avr, yo para cambiar el estado de los pines de salida le hago asi
> 
> PORTA |= (1<<PA0)   Activo el pin 0 del puerto A sin afectar a los demas
> PORTA ^= (1<<PA0) Desactivo el pin 0 del puerto A sin afectar a los demas
> ...




Primero que nada yo uso  CodevisionAVR, entonces para cambiar el estado de un PIN yo utilizo:

PORTA.1 = 0; --> este pone en estado bajo el pin 1 del puerto A
PORTB.3 = 1; --> este pone en estado alto el pin 3 del puerto B
---------------------------------------------------------------------------------------------------------
Para leer el dato desde un pin yo utilizo:

IF(PINA.4) //si el pin 4 del puerto A está en 1...
{
  //codigo aquí
}

IF(!PINA.4) //si el pin 4 del puerto A está en 0...
{
  //codigo aquí
}
---------------------------------------------------------------------------------------------------------
También podés definir:

#define alarma PINB.5

IF(alarma) //si el pin 5 del puerto B está en 1...
{
  //codigo aquí
}

Saludos


----------



## Beamspot (Mar 1, 2011)

El manejo de bits no está definido en C, ni en C++. Así pues, dependiendo del compilador, lo podrás hacer de una manera o de otra.

Yo personalmente uso el WinAVR en casa, y en el trabajo, el IAR, y en ambos casos uso el sistema descrito por Benito: if (PINA&PA0)...

Soluciones hay bastantes, pero ya es más cuestión de gustos, compiladores, y hasta de filosofías de programación. O sea, cuestión de gustos.

Al final, el código compilado queda igual.


----------



## R-Mario (Mar 1, 2011)

Cierto muy cierto, jaja se me olvido decir que tambien utilizo winavr y cierto la verdad no se porque C no soporta el manejo de bits, en fin ojala sigan participando, con sus aportes de tecnicas de programacion


----------



## cristian_elect (Mar 1, 2011)

A mi parecer es asi:
Para tu ejemplo la difinicion PA0 es 0.
PORTA|=1<<PA0   pone a uno PORTA.0
PORTA&=~(1<<PA0)  pone a cero PORTA.0

Para ver bits.
Si porta es entrada.
if(PINA & (1<<PA0) ) si es uno
{
.....
}
else                        lo contrario
...;



if((PINA & (1<<PA0))==0)  si es cero
{
...
}


----------



## R-Mario (Mar 2, 2011)

Cierto ya lo probe cristian y si funciona jeje estoy por terminar mi adaptacion de libreria para manejar la glcd para cuando la termine la subo aca,


----------



## R-Mario (Mar 12, 2011)

Hola de nuevo, pues ya ven aqui dando lata, pues veran tengo dos pequeñas grandes dudas la primera es.
La USART de un atmega8 invierte los datos que saca por la terminal TX?, porque estube haciendo pruebas para enviar por RS232 y use el max232 pero no funciona despues coloque una puerta inversora y funciono, despues quite el max y la puerta y lo conecte directo "claro en la simulacion" y tambien funciono, por lo que pienso que el atmega invierte los datos cuando los manda para cumplir con la norma rs232 pero el max lo vuelve hacer dejando igual el dato, sera eso o que paso aqui jeje.

La otra es con los mugres termopares tipo K segun lei estos entregan 0.04mV por lo que no puedo meterlo al micro entonces use un INA122 y amplifique hasta 122 veces, luego al micro le fije la referencia a 5 volts para que me dieran 5v/1023 = 0.04mV*122, lo de 1023 porque el CAD es de 10bits el chiste es que el mugre ampli no da a la salida 5V/1024 en el proteus, ya le puse la compensacion de Temperatura ambiente al termopar pero nada y luego estube probando y la amplificacion parece que no es lineal en fin que ya no se que hacer, la formula para sacar la amplificacion del operacional es G = 5 + (200K/R) la R me sale de 1709 ohms aprox.

Por el tema de la USART y el Termopar ya imagino que se imaginan que intento capturar la temperatura y enviarla al PC verdad jejej pero bueno hasta ahorita no me ha salido sale gracias


----------



## antiworldx (Mar 12, 2011)

Una, si mal no recuerdo (me da flojera abrir el datasheet), hay un bit de configuracion de los bits del USART que se llama Polarity. Esa es justamente para invertir el nivel de los datos.

Dos, SIMULACION EN PROTEUS... NO SIRVE!!! (por no decirlo mas soez).

Tres, quiero ver tu diagrama de amplificacion del termpar y conectado al micro. Instrumentar termopar no es cosa simple.

Cuatro, el manejo de bits puedes hacerlo así...

int a;
a = porta & (1,2,4,8,16,32,64,128);

los numeros correspondientes al bit que buscas es

bit    no. decimal
0          1
1          2
2          4
3          8
4          16
5          32
6          64
7          128

y listo.

cuatro,


----------



## cristian_elect (Mar 12, 2011)

Una forma facil de configurar un atmega es usar codewizard de Code Vision AVR o del Atmanavr.
Ahorra tiempo.


----------



## antiworldx (Mar 12, 2011)

Pero incluyen los registros de perifericos?
No son los mismos que el registro principal (fuses).


----------



## R-Mario (Mar 12, 2011)

Jaja si cierto ya lo encontre eso de la polaridad, y ya descubri que los de atmel lo hacen porque algunos fabricantes de aparatos hacian su interfaz Rs232 sencilla basada en un par de transistores y otros si usaban el max232 por eso te dan las dos opciones, lo de invertir no me quedo muy claro, yo queria hacer algo asi como dato = ~dato; pero no funciona

Ya subi la imagen del ampli a gracias por responder

No funciono eso de la polaridad al parecer solo funciona con el modo sincrono

This bit is used for Synchronous mode only. Write this bit to zero when Asynchronous mode is
used. The UCPOL bit sets the relationship between data output change and data input sample,
and the synchronous clock (XCK).

Me quiero volver chango

Miren esto es lo que pretendo pero no funciona ni el ampli del termopar y los datos solo se ven bien en la terminal virtual si tiene la compuerta inversora pero si se la quiro ya no funciona y solo salen puros datos mal:enfadado: ahora si ya me enoje voy a invertir la salida del atmega con un transistor y ya

Mugre proteus le puse el transistor en vez de la compuerta logica y tarda mucho en simular ¿POrque?


----------



## cristian_elect (Mar 13, 2011)

Que cosa haces. Mucha nota para algo que si funciona.
Nunca tube problemas con el atmega8 ni con otros series. La configuracion normal que viene el la hoja de datos funciona.


----------



## antiworldx (Mar 13, 2011)

antiworldx dijo:


> Dos, SIMULACION EN PROTEUS... NO SIRVE!!! (por no decirlo mas soez).



Mañana te digo que ocurre con el opamp.


----------



## R-Mario (Mar 13, 2011)

Sale espero tu ayuda, y bueno apenas me acabo de dar cuenta que si realmente quieres un buen medidor de temperatura con termopar debes colocarle un circuito compensador de temperatura ambiente, y como no puedo crear una fuente que entrege 80microVolts pues voy a usar un TMP37 para medir la temperatura ambiente y compensar, e visto en el proteus que todo esto se puede envitar usando un MAX6675 lo malo es que en Mexico no lo venden en ningun lado y maxim lo vende en 16.69dlls + envio y otra alternativa es el ad659 pero igual no lo venden :enfadado::enfadado::enfadado::enfadado:
Bueno voy a seguir viendo que pasa ha y lo de la inversion del dato de la USART no doy con la solucion y la verdad no quiero colocar otro integrado o transistor para invertir la señal


----------



## antiworldx (Mar 13, 2011)

Si sigues haciendo pruebas en proteuss, temo que no voy a poder seguir ayudandote...







Ahora, el termopar debe de conectarse así. Una punta debe de estar en agua con hielos para poder hacer la lectura correcta, y restarle a la lectura de voltaje, el voltaje del termopar que se encuentra a 0º. Ese voltaje lo puedes obtener de la tabla de voltajes de un termopar.

Este método lo he usado sin problemas y es el mas sencillo de aplicar. Sobretodo si lo necesitas para una practica de laboratorio academico. Por otro lado esa no es la correcta conexion del opamp.
Si no tienes un amplificador de instrumentacion en chip puedes armarlo con opamps sin problemas.






de R1 a R4 puedes usar resistencias de 22k (por sugerir un valor, todas deben ser iguales)

R5 y R6 puedes usarlas de 56k, de manera que su ganancia para calcular RG es...

R5+R6 = RG.
 Av.

Rapido, facil y sencillo.



			
				Benito2312 dijo:
			
		

> Mugre proteus le puse el transistor en vez de la compuerta logica y tarda mucho en simular ¿POrque?



*No acepto pruebas en proteuss como prueba*

El ATmega trabaja sin problemas el serial, lo he usado sinfin de veces y sin meterme con la polaridad.


----------



## R-Mario (Mar 14, 2011)

Pues el serial si funciona pero sin el max232 porque al parecer el atmega8 ya invierte la polaridad, en fin del ampli pues mira segun el INA122 es especial como amplificador de instrumentacion y lo conecto tal cual dice su datasheet pero el proteus como que no simula bien, voy a comprarlo para probar lo que pasa que primero queria asegurarme porque aca en mexico cuesta 18 dolares aprox por eso jeje sale luego les cuento va muchas gracias


----------



## R-Mario (Mar 20, 2011)

Hola que tal yo de latoso de nuevo, pues para comentarles que efectivamente proteus y multisim no simulan bien el amplificador de intrumentacion INA122, pero el TINA si lo hace curioso no!!! en fin compre el integrado y trabaja bien porfin ya voy a termina mi tarea, les cuento bien de que se trataba
Consiste en capturar temperaturas en el rango de 0 a 1000 °C usando un termopar, y por supuesto para poder medir desde 0 tenia que llevar un compesador, asi que use un sensor de temperatura de ANALOG el TMP37 para sensar la temperatura ambiente y asi compensar la lectura, tambien el circuito debe enviar la informacion de la temperatura cada 1 segundo a la PC, por el momento solo via RS232, e irla almacenando en un archivo para despues poder graficarla, esta parte del software de la PC aun no la tengo jeje pero bueno para eso todavia tengo tiempo, en fin en cuanto acabe de documentar y armar todo lo subo aca.

Solo tengo una pregunta respecto al famoso SPI de los atmega, y eso es como funciona, porque por mas que intente usarlo para poder conectarle el MAX6675 nomas no pude leerlo, el programa siempre se quedaba en la espera de la transmision o recepcion y no pude por mas que le busque no encontre la solucion y me aburri, use los ejemplos que trae la hoja de datos y nada no pude


----------



## antiworldx (Mar 20, 2011)

jojojojojo
jajajajaja
que paso compadre?
SPI es un protocolo totalmente diferente al USART.
Tu necesitas usar los puertos Rx y Tx del USART nada mas.


----------



## R-Mario (Mar 21, 2011)

antiworldx dijo:


> jojojojojo
> jajajajaja
> que paso compadre?
> SPI es un protocolo totalmente diferente al USART.
> Tu necesitas usar los puertos Rx y Tx del USART nada mas.




HUmm no te entendi porque dices que confundo USART con SPI, si no tienen nada que ver, la parte de la USART ya le di solucion, y ahora estaba atorado con la SPI para usar el MAX6675, quizas tu te confundiste

USART con el MAX232 para enviar datos a la PC
SPI con el MAX6675 para capturar la temperatura del termopar

Bueno si les comente que habia solucionado lo del dato que invierte el MAX232, lo que pasa que el atmega ya invierte la polaridad de la salida, pero el max232 lo vuelve hacer, entonces decidi primeramente colocar una compuerta inversora, pero despues no quize usar otro integrado asi que coloque un transistor para invertir el pulso del atmega y asi funciona hasta ahorita.

Me gustaria saber si alguien conoce algun circuito similar al max232 pero que no invierta la señal

Les agradeceria mucho la ayuda


----------



## antiworldx (Mar 21, 2011)

Cierto, ahora si me atrapaste en una enorme confusión de mi parte... Pero ya busque el datasheet y ya se que quieres hacer...

Muy bien, un tutorial rápido del SPI.

El SPI es un protocolo serial síncrono, eso significa que requiere una señal de reloj y seleccion de dispositivo (chip select).
El SPI trabaja por pares, donde esta el dispositivo maestro (el que genera la señal de reloj), y el esclavo.

Este circuito esta diseñado para ser un circuito esclavo, de tal manera que el atmega debe ser configurado como maestro. Su transferencia de datos esta hecha para trabajar a 16 bits. (ojo aquí) El AVR solo soporta transferencias de 8 bits, entonces se necesitará hacer truco en software para leer los nibles alto y bajo del convertidor.

De hecho la manera de leer y escribir en el SPI es similar al USART.
Escribes en el buffer y el solito envia, y cuando llega, enciende la bandera.
Te recomiendo que uses interrupciones de llegada y envio para hacer mas ágil tu software.

P.D. Nunca he necesitado invertir las señales del usart con el max232. El problema es la cochinada de programa feo del proteuss... no sirve, es como la quinta vez que te lo comento. Yo he hecho bastantes aplicaciones con el usart del AVR, incluyendo una donde graficaba entiempo real datos de un motor brushless.


----------



## R-Mario (Mar 21, 2011)

Jeje wueno pues  si fijate que si el proteus le falla muchas cositas.

Aver lo del SPI entiendo la teoria y eso pero mi duda que por cierto no he podido resolver es esta

Esclavo = MAX6675
Maestro = Atmega8, el master genera el clock

La hoja de datos da estos ejemplos

void SPI_MasterInit(void)
{
DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}
void SPI_MasterTransmit(char cData)
{
SPDR = cData;
while(!(SPSR & (1<<SPIF)));
}

Es decir inicia el modulo como maestro y luego esta la funcion que transmite hasta aqui todo bien.

Pero entonces como le hago para leer en modo Maestro, A caso solo basta con hacer esto:

cData = SPDR
while(!(SPSR & (1<<SPIF)));

Porque ya lo hice y no funciona.

Respecto a lo que mencionas que el MAX6675 envia 16bits eso ya vi como se puede solucionar y eso es controlando la terminal SS, ya que el atmega automaticamente deshabilita el esclavo cuando ha leido los 8bits pero si controlamos la terminal SS con otro puerto pues podemos mantenerla activa mientras solicitamos una segunda lectura.

Aver si me explique bien sale ha y muchas gracias por el apoyo que me brindan


----------



## R-Mario (Mar 27, 2011)

Nadien que me ayude!!!


----------



## antiworldx (Mar 27, 2011)

Ha es que, perdon por no contestarte pero, cuando tu envias un dato, al mismo tiempo recibes el dato del esclavo entonces quedaria algo asi...


```
char SPI_MasterTransmit(char cData)
{
 SPDR = cData;
 while(!(SPSR & (1<<SPIF)));
 cData = SPDR;
 return cData
}
```

Esa funcion hace dos cosas, te envia datos y al mismo tiempo te regresa el dato que recibio mientras transmitio... de manera que puedes implementar la funcion asi.


```
char datoentrada;
char datosalida;

datosalida = SPI_MasterTransmit(datoentrada);
```

y así, estas recibiendo lo del esclavo, al mismo tiempo que envias lo del maestro.


----------



## R-Mario (Mar 28, 2011)

OK hasta ahi entiendo el datalle es el siguiente:

Que pasa si el esclavo solo es de los que envian datos pero no recibe nada por ejemplo el MAX6675 solamente envia los datos de la temperatura pero no recibe nada entonces el codigo que me pasa funcionara bien??

O tendria que enviar como dato salida un 0x00 y esperar recibir el dato de entrada que envia el MAX6675; bueno mientras voy a probar, a y una nota PROTEUS invierte las señales del puerto RX y TX de los Atmegas y cuando lo simulas precisas invertir esa señal pero en la realidad los atmegas no lo hacen en resumen.

En proteus haces AtmegaTx  -> 74LS04 -> Max232 -> PuertoSerie
En la realidad AtmegaTx -> Max232 -> PUertoSerie

Mugre proteus, por cierto alguien sabe si existen librerias para simular los ATMEGA en MULTISIM, en especifico el atmega32


----------



## Basalto (Mar 28, 2011)

No te fies de todo lo que te simula el proteus!! Es mejor que lo montes y lo mires. Tuve probremas simulando puertos USB, LCDs y USART. En el proteus no me funcionaban y cuando los montaba funcionaban a las mil maravillas. Un saludo


----------



## antiworldx (Mar 28, 2011)

Benito2312 dijo:


> O tendria que enviar como dato salida un 0x00 y esperar recibir el dato de entrada que envia el MAX6675



Ya tienes tu respuesta.



Benito2312 dijo:


> a y una nota PROTEUS invierte las señales del puerto RX y TX de los Atmegas y cuando lo simulas precisas invertir esa señal pero en la realidad los atmegas no lo hacen en resumen.





Basalto dijo:


> No te fies de todo lo que te simula el proteus!! Es mejor que lo montes y lo mires.



Ya se me esta haciendo un poco cansón que sigas trabajando el proteuss. Casi desde un inicio te dije que mejor te vallas directamente a la prueba física. No creas que lo digo por jugar.

Mejor enseñate a usar los depuradores de los compiladores. 

Seguimos al pendiente...


----------



## R-Mario (Mar 28, 2011)

Ok ok pero no te enojes jeje, bueno hay que admitir que se bonito como se simula en preteus, y que cuando tienes que esperar una semana a que te llege el circuito es bueno ir practicando un poquito, y bueno los depuradores que trae el avr studio junto con winavr pues son algo fastidiosos en fin voy a probar la transmison spi, sale tema cerrado


----------



## antiworldx (Mar 28, 2011)

AVR studio trae un pequeño detalle en su depurador. Los timmers no los ejecuta bien, asi que tampoco te fies de ese asunto.

Es facil, cuando ejecutas el depurador, y habilitas los timers, estos no retienen la configuracion y hacen cosas raras. Es el unico detalle que le he observado al AVR studio.

Excelente, antes de cerrar el tema, cuenta que ocurre con el termopar.


----------



## R-Mario (Mar 28, 2011)

Jeje si cierto aver les cuento esta larga historia.

Yo estudio es el ipn en mexico y estoy en octavo semestre total que el profe de instrumentacion nos pidio que hicieramos una interfaz para capturar la temperatura que mide un termopar tipo K y lo mandara a grafica a la PC y ademas una caja de potencia a la que se le metieran 4 a 20mA y pudiera manejar por PWM una resistencia calefactora de 100watts "COSA que todavia no he hecho"

En fin pues luego luego a buscar como hacerlo, muchos en el salon lo estan haciendo con el MAx6675 otros van usar el AD595 porque fueron con los que el profe dijo que podian hacerlo, "bola de entendidos" no saben buscar mas alla siempre lo que el profe les dice, bueno la cosa esta en que como grupo que somos valen para pura mama porque son bien envidiosos cada quien con lo que hacen o bajan de internet y no te pasan nada de nada y cada quien se rasca como puede cosa que veo muy mal pero bueno.

Asi que como casi no soy nada "che necio" pues decidi buscar otra alternativa algo que si fue dificil porque toda la info en internet sobre interfaces para termopar se basan en el AD595 y el MAX, pero bueno finalmente el la pagina de TexasInstrument encontre una seccion que dice Intrumentation y ahi encontre amplificadores para intrumentacion "porque se supone que soportan altas temperaturas son muy estables muy bajo offset etc, etc" en este caso vi el INA122 un operacional con ganancia de hasta 10000 hecho con resistencias grabadas con lasser etc etc y bueno dije pus con este

Despues me tope con el problema de medir temp ambiente con el termopar y esto lo hice con un tmp37 asi que mido temp ambiente con el tmp37 y lo sumo a lo que mide el termopar es decir compenso la lectura, luego el detalle del micro, nuevamente todos usaron el mugre pic16f4550 porque es el que anda en internet pero nuevamente hay va el necio y decido usar el atmega8 y luego una lcd y luego pues todo lo demas al fin me queda y pude descansar.

Subo una imagen de como es el circuito, el codigo luego se los paso porque honestamente no me gustaria que esos gandallas encontraran mi codigo y capaz que lo entregan y para que quieren no.

Por ultimo perdon por todo este rollo pero necesitaba contarlo jeje y nada mas que pase la fecha limite para la entraga y lo subo

Pero si detallo dos cosas
Primera la lectura del ADC sufre de ruidos cuando se arma en protoboard y un poco aun estando en la PCB esto porque no use las tecnicas para evitar ruidos, pero lo solucionas tomando  en mi caso 10 muestras  y luego las promedio

Segunda 
El INA122 es muy delicado casi cualquier cosa amplifica, entonces mucho cuidado con los ruidos parasitos y otros detalles.

Tercera 
Use el LM358 es necesario porque los atmegas chupan mucha corriente cuando lee los puertos entonces el tmp37 con sus 3mA pues hacia que se callera el voltaje al leer con el micro, igual con el ina122 entonces por eso coloque el OP con ganancia unitaria.

el ina esta amplificando aprox 62.5 veces y el ADC del avr esta a 10bits 

Asi los 4E-5Volts del termopar *62.5 = 2.56Vref/1024 bueno aprox


----------



## antiworldx (Mar 28, 2011)

Ten cuidado con tu lenguaje, corrigelo antes que manden todo el comentario a moderacion.


----------



## R-Mario (Mar 28, 2011)

Oye la caja de potencia la podria implementar con el atmega8 usando su modulo pwm, aver si mido la caida de tension sobre una resistencia de 250 ohms al hacerle circular la corriente de 4 a 20mA en el caso de que haya 4mA tendre 1Volt y en caso de que haya 20mA tendre 5volts luego esto lo meto al CAD del atmega y despues hago que el PWM quede en funcion del valor leido por el CAD, humm eso podria resultar??? Pues voy a tener que leer la parte del PWM en el atmega8, me vendrian bien ideas sobre todo la parte de configuracion del pwm porque por lo que es leido hasta ahorita esta algo confuso habla de muchos registros


----------



## antiworldx (Mar 28, 2011)

No entiendo que quieres hacer con la caida de voltaje. El pwm es un modulo mucho mas sencillo que el ADC. Pero explicame mejor tu idea.


----------



## R-Mario (Mar 28, 2011)

A mira se trata de lo siguiente
En la industria los sensores en general envian la informacion en forma de corriente no de voltaje, el estandar dice que esta corriente va desde 4mA representando "NADA" hasta 20mA representado "TODO" entonces tengo que hacer una circuito que controle una resistencia de 100Watts con estas señales de 4 a 20mA, ejemplo si me llegan 8mA la resistencia debe calentar a la mitad "(20 - 4mA) / 2 = 8mA", para calentar debo usar el PWM en este ejemplo el PWM estaria al 50% de ciclo util, ahora bien el micro no recibe corriente por eso proponia poner una resistencia de 250 Ohms y hacer que la corriente fluya sobre ella asi para 4mA leeria 1Volt y para 20mA leeria 5Volts ahora si le meto esto al CAD y hago que el PWM varie de acuerdo al voltaje leido en la resistencia, como vez cres que se pueda, hechame la mano con la parte del PWM


----------



## antiworldx (Mar 28, 2011)

Muy bien, primero quiero que hagas lo siguiente.

Convertir de corriente a voltaje, y eso se hace con el siguiente circuito







y su formula es:

VOUT =-RI

de tal manera es que si a 20 mA quieres tener 5V para que el ADC te indique de salida 255 (en caso de 8 bits) entonces tu deberás calcular...

VOUT = -R I.

R = -VOUT / I

R = -5V / 20mA

R= 250 ohms

Esta es la forma correcta de acondicionar los sensores de corriente. 

Ahora, revisa ese circuito, y en la noche te mando informacion sobre el pwm que ahorita ando un poco ocupado y necesito sacar el datasheet. No me se todos los registros de todos los micros de memoria.


----------



## R-Mario (Mar 29, 2011)

antiworldx dijo:


> Muy bien, primero quiero que hagas lo siguiente.
> 
> Convertir de corriente a voltaje, y eso se hace con el siguiente circuito
> 
> ...




Ya estas, revisando...


----------



## R-Mario (Mar 30, 2011)

HOla que tal de nuevo aca, pues si ya hice pruebas y si funciona mucho mejor que una simplona resistencia jeje bueno ahorita sigo leyendo para entender bien el pwm del atmega, la verdad si esta algo largo el tema y como se mescla mucho con los timer del micro pues hay que leer tambien esa parte


----------



## antiworldx (Mar 31, 2011)

No es dificil, mas bien no estas familiarizado con los términos. 
Leelo y pregunta las dudas... Yo tengo algunos PWM funcionando, pero todos los micros los programo en ensamblador y a lo mejor te confundo si te pongo algunos codigos.


----------



## R-Mario (Mar 31, 2011)

Nop no es que confunda terminos es solo que hay que configurar varios parametros para hechar andar el pwm, pero bueno ya estoy en eso ya genere una señal que va variando su ancho, ahora voy aver como hacerlo en funcion del nivel de tension que lea del adc


----------



## antiworldx (Mar 31, 2011)

Ok, si vas a manejar 8 bits, lo mas facil es que al timer le pongas un top de #0xFFh de manera que el dato que lees del ADC directamente lo arrojes al TMR directamente. Eso para que hagas prueba. Si funciona, entonces ya podemos jugar con mas cosas.


----------



## R-Mario (Mar 31, 2011)

Andale exactamente eso es lo que trato de hacer ahorita, pero no logro configurar para que haga la conversion a 8 bits, eso como se hace porque parece ser que me esta haciendo conversion a 10bits aver esto es lo que he hecho:


void config_pwm_8()
	{
	TCCR2 = (1<<WGM20)|(1<<WGM21)|(1<<COM21)|(1<<CS20);
	TCNT2 = 0xFF;	//Aqui ponemos el valor con que se compara 
	OCR2  = 0;		//Contiene el valor que se compara con TCNT2 y generar la pwm
	}
Esta en PWM rapida, usando el timer2 de 8bits, modo no invertida con salida en OC2

Y el ADC lo configuro asi:

int8_t LEE_ADC()
{
/* 	
	@ 1Mhz y Preescala = 4 se tienen fadc = 250KHz resolucion 8bits en ADC0
	Referencia interna de 2.56V con ajuste a la izquierda
*/
	ADMUX = (1<<REFS1)|(1<<REFS0)|(1<<ADLAR);	
	ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADPS1);
	_delay_ms(1);
	return ADCH;	
}


Se supone que asi deberia hacer conversion a 8bits porque la frecuencia es superior a 200Khz y ademas estoy poniendo ADLAR en 1 para que lo ajuste a la izquierda y luego leo la parte alta, pero no da bueno despues lo que hago es esto

OCR2 = LEE_ADC();

Y va bien pero cuando sobrepasa los primeros 8bits pues ya no varia, honestamente no tengo un osciloscopio pero lo probe con un foco y parece ser que no llega hasta pwm = 100%, luego lo probe en proteus para ver y en la simulacion tambien aparece que esta haciendo conversion a 10bits y yo quiero que lo haga a 8bits

Nota si leei la parte baja para que actualize el registro ADC

Alguna idea de como forzo a que sea conversion de 8bits

Ya nomas me falta eso lo demas ya lo tengo imaginado jejeje


----------



## antiworldx (Mar 31, 2011)

Benito2312 dijo:


> luego lo probe en proteus para ver y en la simulacion tambien aparece que esta haciendo conversion a 10bits y yo quiero que lo haga a 8bits



Y dale con lo mismo... Ya desinstala eso que nomas te confunde mas.

Para que puedas leer los valores, solo usa el ajuste a la izquierda y lee la parte alta, eso es todo, no tiene falla. Usa la conversion con preescalador a 8, no necesitas mas para lo que quieres hacer. Incluso todavia se me hace rápido.

Otra cosa, recuerda conectar los voltajes de AVCC y AVSS, son la referencia de voltaje del ADC.


----------



## R-Mario (Mar 31, 2011)

antiworldx dijo:


> Y dale con lo mismo... Ya desinstala eso que nomas te confunde mas.
> 
> Para que puedas leer los valores, solo usa el ajuste a la izquierda y lee la parte alta, eso es todo, no tiene falla. Usa la conversion con preescalador a 8, no necesitas mas para lo que quieres hacer. Incluso todavia se me hace rápido.
> 
> Otra cosa, recuerda conectar los voltajes de AVCC y AVSS, son la referencia de voltaje del ADC.



Pues si ya los conecte, y pues del proteus la verdad cuando estas escasos de aparatos de medicion pues si te da mucho por usarlos, yo por ejemplo no he podido comprarme un osciloscopio aca en mexico andan por los 8000 pesos uno mas o menos y un multimetro fluke osea algo bueno estan en 2500 en fin entonces pues hay que hacerle con lo que se tiene pero bueno mañana voy a probar en la escuela aver como sale la señal sale gracias y luego te cuento


----------



## antiworldx (Mar 31, 2011)

El PWM no tiene problema, conecta un led, y juega con su brillo.
Los led te pueden dar una cantidad de informacion cualitativa muy valiosa... Sabiendolos usar.


----------



## R-Mario (Abr 1, 2011)

Pues ya me quedo lo del pwm ahora la parte del conversor de corriente a voltaje no me va muy bien, ya me prestaron una fuente de corriente para probar porque no me da la salida en voltaje correcta, como sale la señal invertida pues la volvi a invertir y no sale, algun circuito por hay??


----------



## antiworldx (Abr 1, 2011)

Osea... como? No entiendo tu problema, habias dicho que si funcionaba bien...

Ha, y si quieres que salga positiva la señal, pues conecta el sensor al revez...


----------



## R-Mario (Abr 1, 2011)

Bueno he de dicir que si funciona si usas una fuente simetrica pero, no quiero usar una fuente simetrica


----------



## antiworldx (Abr 1, 2011)

¬¬ primero que funcione todo el circuito así, y no en chafeuss... Si el circuito y atmega ya trabaja todo correctamente, entonces ya como por ultimo, te digo como lo trabajes con fuente simple. Solo que ahorita como es fase de desarrollo, hay que eliminar todos los errores posibles en diseños.


----------



## R-Mario (Abr 1, 2011)

A ver es que eso pasa por no explicarme bien, mira ahorita toy en la escuela y ya vi la salida del PWM y si funciona bien, le meti el voltaje con un potenciometro para ir variando y va bien, a mayor voltaje el ancho crece, cuando llego a 5volts el ancho se vuelve al 100% osea eso ya me quedo, ahora estoy con la parte de la entrada, cuando me mandaste el convertidor de corriente a voltaje lo probe con un lm358 y funciono bien, claro esta que use una fuente simetrica y efectivamente sale bien pero en el circuito real no quiero usar una fuente simetrica y sin ella ya no funciona, por cierto tendras una referencia a un mosfet que pueda manejar una carga de 100Watts que se acople bien a señales digitales, por ahi oi hablar una ves de mosfet que diseñan especial para recibir de 0 a 5V en su base


----------



## antiworldx (Abr 1, 2011)

Esos mosfet de 0-5V en gate, no los he conseguido fácil, y son mucho mas caros, lo que he hecho mejor es usar doble mosfet. Que frecuencia usaras de PWM? Que vas a controlar?

Y pues para controlar 100W, pues nomas ve que corriente maneja el mosfet, si no te da la corriente o se queda corto, usalos en paralelo y con la suma de sus corrientes ya calculas si la potencia te es suficiente.

Por otro lado, el truco para no usar fuente partida, es que conectes el opamp, a tierra y a +5V. El truco aqui es que, al sensor lo conectes a una tierra virtual, usando dos resistencias identicas como divisor de tension. De manera que para el sensor y el opamp, tendras tierra virtual, y  +/- 2.5V
Me explico? Las resistencias deben ser lo mas pequeñas posibles sin que se quemen, claro que sacrificando el consumo de corriente del circuito. Pero si no es una aplicacion a baterías, no habra problema.


----------



## R-Mario (Abr 1, 2011)

Poca aprox va ser 4Khz, bueno voy a tratar de buscar esos mosfet porque si me facilitaria, igual y uso un optotriac en fin y bueno lo de la virtual pues yo creo que si lo voy hacer asii, bueno dejame quemar algunas cositas y luego te cuento sale gracias


----------



## R-Mario (Abr 2, 2011)

Encontre este en un libro y ya le entendi a la explicacion, he probado con el lm358 y parece funcionar, ahora que propones para continuar, en realidad tengo una pregunta, si le meto 1volt el micro debe generar un pwm de 0% ciclo util y si le meto 5volts debe generar el pwm al 100% como hago eso en el micro, cuando estaba probando nomas lo que hacia era restar al valor leido por el ADC lo de 1volt para que generar 0% de pwm pero cuando llega a 5volts entonces produce el pwm correspondiente a 4Volts porque se lo reste entonces nunca llega al 100% como hago eso, alguna idea


----------



## antiworldx (Abr 2, 2011)

El valor decimal, de 1 volt, es el valor 51. Esto nos deja que, el ADC variara de 51 a 255, dando un total de 204 valores.

La forma mas facil es que, el timer tenga como TopCount, el valor 204, entonces al valor del ADC, le restas 51 y el valor resultante, lo metes directamente al PWM y ya es todo. Así te evitas hacer multiplicaciones por punto fijo para hacer una proporcion.


----------



## R-Mario (Abr 3, 2011)

antiworldx dijo:


> El valor decimal, de 1 volt, es el valor 51. Esto nos deja que, el ADC variara de 51 a 255, dando un total de 204 valores.
> 
> La forma mas facil es que, el timer tenga como TopCount, el valor 204, entonces al valor del ADC, le restas 51 y el valor resultante, lo metes directamente al PWM y ya es todo. Así te evitas hacer multiplicaciones por punto fijo para hacer una proporcion.



Aver hice esto pero nunca llega el pwm al 100%

void config_pwm_8()
	{
	TCCR2 = (1<<WGM20)|(1<<WGM21)|(1<<COM21)|(1<<CS20);
	TCNT2 = 204;	//Aqui ponemos el valor con que se compara 
	OCR2 
        }

while(1)
{

	lecturaADC = LEE_ADC();

	if(lecturaADC <= 51)  //Para mantenerlo en 0 cuando haya 1volt
		{ OCR2 = 0;}
	else
		{   // caso contrario entonces le resto 51 pero se supone que el topcounter es de 204 porque no llega a 100% en el pwm si ha 255 del adc menos 51 es 204 pero no da
		OCR2 = lecturaADC-51;
		}

}


----------



## antiworldx (Abr 3, 2011)

Ya vi que esta pasando... Estas usando el timer 2, y no recordaba que este no puedes controlar el Top Count.

El PWM esta trabajando desde 0 hasta 255 y ahi el problema. Aqui tenemos una de dos.
O usas el Timer1 para poder controlar el TopCount, o multiplicamos los valores del ADC por un numero fraccional.

Tu decide cual camino tomar y ya te digo como se hace.

P.D. Me deba flojera abrir el datasheet XD XD


----------



## R-Mario (Abr 3, 2011)

Orale esa no me la sabia, humm tu que me recomiendas, yo pienso que para no modificar la parte del adc mejor multiplicamos pero eso como se hace?? oye por cierto conoces las librerias avrlibc que tal andan, hoy voy a probarlas aver que

Mejor aguantame tantito estoy jugando con el timer1 aver que saco sale, aunque si dime como es eso de multiplicar por un fraccional

Esto no funciona aun con el timer1 no se modifica el TOPcounter del TCNT1, mira hice esto y no funciona
  DDRD = 0xFF;
  TCNT1 = 204;	//Hasta aqui va contar
  OCR1A = 102; // ciclo util
  ICR1 = 0xFF;  //Resolucion a usar en este caso a 8bits

//PWM no invertida, en su modalidad rapida con prescala a 1
  	TCCR1A = (1<<COM1A1)|(1<<WGM10);
    TCCR1B = (1<<WGM12)|(1<<CS10);


----------



## antiworldx (Abr 3, 2011)

El problemita es que yo programo exclusivamente en ensamblador, el C lo uso para hacer aplicaciones para PC en windows.
Así que no se como este esa libreria.

Y para lo de tu problema, intenta con esto.


```
float a;
float b;
b = 1.25;
a = LEE_ADC();
if (a > 50)
{
 a = (a-51)*b; 
 OCR2 = a;
}
```

A ver como queda esto...


----------



## R-Mario (Abr 3, 2011)

Me estoy empezando a dar cuenta que solo tu respondes ¿porque?, jeje en fin pues si si funciona esa relacion pero la pregunta forzada ¿De donde sale ese 1.25? digo se que sale de 255/204 pero porque o cual fue tu razonamiento?? 

Oye pues por adelantado te doy las gracias porque entonces ya quedo esto, un optotriac un irfz y le puse un foco de 60w y si jala bien, ahora nomas porque me sobra tiempo voy a ponerme a usar el pwm pero con resolucion a 10bits aver que me sale, imagino que se puede controlar mucho mejor el brillo pues tendre 1024 pasos a diferencia de los 255 en fin, aver como se ve asi 

POr cierto usar (int8_t)(float A) para forzar la conversion un entero de 8bits no funciona pero si haces (char)(float A) si funciona y no sabo porque


----------



## antiworldx (Abr 3, 2011)

Pues supongo que como yo ya llebaba el tema encausado, ya no tiene caso confundir con mas ideas, bueno al menos yo asi cuando veo un tema ya con alguien que lo va llevando, no digo ya nada para no confundir mas a la pobre victima.

Y sobre ese numero magico, salio con la famosísima y universal regla de 3.

(255/204)*numADC
Simplemente hice una proporcion.

Y si, sospechas bien, si usas el ADC a 10 bits y el timer1, tendras mas resolucion en el PWM.

Y sobre ese detallito de los flotantes y enteros, ahi si te voy a quedar mal, por que ya es una cuestion del compilador, y pues como te repito, yo programo los microcontroladores exclusivamente en ensamblador. Entonces yo no tengo problemas de pelearme con los compiladores. Al unico compilador C que si le conozco bien es al de Borland para aplicaciones windows.


----------



## R-Mario (Abr 3, 2011)

O si hermosa regla de 3 de cuantas nos han sacado o al menos da con muchas soluciones, sale mi hermano nos vemos luego subo lo que he hecho digo no es mucho pero espero le sirvan despues a alguien mas


----------



## antiworldx (Abr 3, 2011)

Pues yo cuando empezaba con estos circos, un ejemplito de estos me hubiera ahorrado una tarde de sufrimiento. Ya le servira a alguien mas, eso tenlo por seguro.


----------



## R-Mario (Abr 4, 2011)

Oigan que opinan del microcontrolador DS89C450 de Maxim, creen que el nucleo 8051 ya paso de moda, o creen que todavia tenga mucho sentido aprenderlo, yo se usar el 8031 y pues practicamente igual al ds89c450 claro esta este ultimo solo le he visto como ventaja su memoria flash de 64KB y su habilidad para ser programado via serie rs232, que opinan a cerca de este micro, yo he visto que se usa mucho en la industria ¿Porque?


----------



## cristian_elect (Abr 4, 2011)

En la industria mucho se usa la marca Infineon.


----------



## R-Mario (Abr 4, 2011)

Infineon pero que nucleo usan, o es propietario de infineon


----------



## cristian_elect (Abr 4, 2011)

Hay en al pagina dice 8051, C166 y MISP es sus distintas gamas de micros.


----------



## R-Mario (Abr 4, 2011)

POr lo que he estado viendo ahorita, si sigue mucho en uso este microcontrolador y al parecer el nucleo 8051 todavia da para rato


----------



## R-Mario (Abr 9, 2011)

Hola otra vez yo consultando, y esta vez para saber que interruptor de AC me recomiendan, tengo que aplicarle el PWM, al principio se supone que hiba a ser con CD e hiba usar un mosfet, pero ahora ya me la cambiaron y debe ser con AC, pero el mosfet con AC no va bien, y el triac pues no responde al AC, entonces estaba viendo la posibilidad de usar un IGBT, pero es la primera vez que trabajaria con uno, alguna idea, recomendacion, sugerencia o queja de porque pregunto mucho jeje todas son aceptadas, o me recomiendan mas que rectifique la señal de AC en este caso es de 120V y despues de rectificada se la aplico a la resistencia calefactora con un mosfet, encontre Switch para AC 
http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00003319.pdf

pero no entiendo si funcionaria con PWM, pues al ser alterna como es que responderia este dispositivo al PWM

Ayuda porfa


----------



## antiworldx (Abr 9, 2011)

A ver, no entiendo que quieres... quieres controlar la amplitud de voltaje de una corriente AC?
Como los dimmer de los focos domésticos para controlar la luminosidad?


----------



## R-Mario (Abr 9, 2011)

OYe porque te pusiste antiworlxd?? bueno te explico, hiba usar el pwm para controlar la temperatura de una resistencia para calentar agua de esas comerciales, entonces hiba usar CD, pero ahora me piden que use AC, pero como funciona el pwm con AC, "Eso se puede" que no el pwm solo se aplica a DC, en fin tengo que controlar la temperatura pero con el uso de PWM, como le hago, y si mejor rectifico la AC y la paso a CD, eso seria una buena solucion?? y bueno pues si es parecido al dimmer al fin y al cabo creo que hacen lo mismo


----------



## R-Mario (Abr 9, 2011)

Otra pregunta mas, fijate que estoy jugando con el rtc ds1307 de maxim, total que no he podido leer desde el, segun el programa si escribe bien puesto que no se traba pero cuando intento leer no lee nada se queda trabado alguien conoce la rutina para leer con I2C porque la que hice no funciona, o no se si me esta fallando el concepto de NACK porque tengo que enviarlo pero no entendi bien desde la datasheet como se envia podrian explicarme esto
case i2c_Datos_Salen:
		TWDR = dato;
		TWCR = (1<<TWINT) | (1<<TWEN);
		while (!(TWCR & (1<<TWINT)));	//Esperamos a que finalize
		return (TWSR&0xF8);	
		break;

		case i2c_Datos_Entran:
		TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
		while (!(TWCR & (1<<TWINT)));	//Esperamos a que finalize
		return TWDR;

La que dice datos_salen es para grabar y al parecer eso lo hace bien pero en Datos_Entran se queda en el ciclo while, la hoja de datos dice que para finalizar la lectura se debe enviar el NACK pero no se como se envia, la datasheet del atmega dice que no es accesible por el usuario


----------



## antiworldx (Abr 10, 2011)

Nunca he usado el I2C, ahi si te voy a fallar para no decirte mentiras.
Por otro lado, mañana te cuento como es que se trabajan los triac para controlar el voltaje promedio de una corriente AC. No es algo asi que muy sencillo que digamos. Tiene su chiste.
Es que ahorita vengo llegando de la parranda XD XD, y ya traigo sueño...


----------



## dukex (Abr 10, 2011)

Benito2312 dijo:


> pero como funciona el pwm con AC, "Eso se puede" que no el pwm solo se aplica a DC, en fin tengo que controlar la temperatura pero con el uso de PWM, como le hago, y si mejor rectifico la AC y la paso a CD, eso seria una buena solucion?? y bueno pues si es parecido al dimmer al fin y al cabo creo que hacen lo mismo



Hola, claro que se puede. Pero para situaciones y cargas particulares. Yo lo probé... lee este tema (_https://www.forosdeelectronica.com/f12/controlar-tension-alterna-corriente-continua-53111/index2.html#post468813_) y de una véz miras la discución:cabezon:... en varios sitios de la red como edaboard.com hablan de este método.  El cuál ha sido muy anatematizado por un par de foristas........   

mira con tus propios ojos y pruébalo para que nos cuentes como te fué....  puede que te funcione, como puede que no.. eso depende de ese sistema que vas a controlar.

La idea es utilizar una frecuencia relativamente Baja de PWM, que abarque unos 20 semiciclos de la señal de potencia, así tendras unos 20 "niveles" de potencia. Si tu red trabaja a 50Hz entonces serán como 200ms en el PWM,  unos 5Hz.

Otra manera que se menciona un par de veces acá en el foro, es utilizar un puente rectificador y mosfet, un IGBT también servirá. Así tendrás encendido y apagado instantáneo aprovechando el PWM a una frecuencia mucho mas alta....

PD: espero que no se empiece una discusión en este tema, debido al frankenstein PWM-OptoTriac


Por otro lado......



Benito2312 dijo:


> Otra pregunta mas, fijate que estoy jugando con el rtc ds1307 de maxim, total que no he podido leer desde el, segun el programa si escribe bien puesto que no se traba pero cuando intento leer no lee nada se queda trabado alguien conoce la rutina para leer con I2C porque la que hice no funciona, o no se si me esta fallando el concepto de NACK porque tengo que enviarlo pero no entendi bien desde la datasheet como se envia podrian explicarme esto
> case i2c_Datos_Salen:
> TWDR = dato;
> TWCR = (1<<TWINT) | (1<<TWEN);
> ...



Ya miraste por acá??  http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=49778 

Tuve una tarea similar....,  yo trabajo con el codevision el cual no tenía la libreria TWI, o por lo menos la version con la que estaba trabajando... 

Luego, un dia después de buscar mucha información y a punto de empezar a desarrollar esa libreria, me llegó un e-mail de Adriana Haiduc de HP infotech informandome que habia una nueva version de mi codevisionAVR... la descargué y púm!!! ahí estaba la nueva libreria  jejejej me ahorro muchísimo trabajo....

Arriba en el vinculo que lleva a el foro de AVRfreaks dicen que hay un proyecto que explíca mucho mejor lo que necesitas.... pero te toca registrarte para verlo.

Paz y Saludos


----------



## R-Mario (Abr 10, 2011)

PD: espero que no se empiece una discusión en este tema, debido al frankenstein PWM-OptoTriac, jejeje muy cierto todo mundo anda emocionado con su opto y triac, pues mira ya le di una mirada a eso que mencionas del pwm, sin embargo por lo que entendi "a no ser que no haya entendido nada" es que esto solo funcionaria con el semiciclo positivo, ¿¿¿???, en fin la segunda, pues he intentado usar codevision pero la verdad no me late, ya estoy muy metido con WinAvr gcc entonces no veo ahorita la necesidad de cambiarme, pero aun asi voy a ver como implementa codevision la rutina del twi, aver si se la copio jeje

Chales ya cheque el codigo de la twi, pero la verdad estos cuates se emocionan haciendo codigo y termino mas confundido mejor voy a hacer el mio jejej mas facil y sin tantas complicaciones


----------



## dukex (Abr 10, 2011)

Obvio, no quiero que te cámbies jejejej sólo te estaba contando la historia..... Pero revizaste la página AVRFreaks? allí hablan sobre AVR gcc no sobre codevision.

Sobre frankestein, hablan de un semiciclo haciendo mencion a 20 semiciclos como el tiempo del PWM,  funciona sobre ambos ciclos.  Mencionan es que se deberia utilizar un Zero Crossing.

Saludos


----------



## R-Mario (Abr 11, 2011)

Oye me acabo de topar con un compilador llamado MikroC AVR, alguien a trabajado con este compilador, lo estoy probando y parece muy bueno, me gusta hasta ahorita, alguien tiene referencias de el


----------



## antiworldx (Abr 11, 2011)

Yo he usado el mikro C para pics y viene muy completo. Trae rutinas de teclado, lcd y mas chucherias. Pero en lo personal no me gusta tener codigo que no conozco jejejeje. 

Por mi puedo decirte que no tuve problemas con el las veces que lo he usado.


----------



## R-Mario (Abr 11, 2011)

antiworldx dijo:


> Yo he usado el mikro C para pics y viene muy completo. Trae rutinas de teclado, lcd y mas chucherias. Pero en lo personal no me gusta tener codigo que no conozco jejejeje.
> 
> Por mi puedo decirte que no tuve problemas con el las veces que lo he usado.



Pues si, mira que cosas, me llevo solo 20 minutos "resolver" el problema del DS1307 y la TWI, muy bonito compilador, aunque honestamente quien sabe que tanto haga por dentro, voy a seguir urgando entre sus codigo .h a ver que le saco de bueno, ok mientras voy a emocinarme, nota tambien tienen compilador para PIC, 8051 y ARM y todos en tres lenguajes distintos, C, Pascal y BASIC, y bueno ya porque paresco mas vendedor que otra cosa jaja


----------



## diego666 (Jun 25, 2011)

Hola mira este video talves y te puede ayudar:


----------



## R-Mario (Jun 25, 2011)

Muy bueno yo creo que a nadien le quedaria duda sobre este tema ¿O si? jejeje gracias diego diabolico 666


----------



## gonpa (Feb 9, 2012)

Hola, yo he tenido y estoy teniendo un problema con la uart del atmega8L en este caso.
yo configuro todo para 9600 baud 8datos sin paridad 1 bit de stop pero no se por que no logro que se comunique a la pc. uso el term95 y con el attiny2313 no he tenido problemas. espero que me puedan ayudar por que ya intente de todo como por ejemplo invertir la señal aunque solo por que en proteus funcionaba asi, pero bueno es que ya no se que hacer dejo el codigo:

#define F_CPU 8000000UL	
#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>

void initUART(unsigned int ubrr) 
{
	UBRRH = (unsigned char) (ubrr >> 8);				//Guardo el bautrate en el registro
	UBRRL = (unsigned char) ubrr;						//si supera un byte el 2°byte se guarda en el byte alto
	UCSRB = (1<< RXEN)|(1<<TXEN);//|(1<<RXCIE);	        //Habilito recepción, transmisión e interrupcion RX 
	UCSRC = (1<<UCSZ1)|(1<<UCSZ0);						//bit de datos = 8 
	//Registro de estado de la UART
	//UCSRA=|RXC|TXC|UDRE|FE|DOR|PE|U2X|MPCM|
}
int USART_Transmit(char data,FILE *stream )
{
	if (data =='\n')
	USART_Transmit('\r',stream);
	while ( !( UCSRA & (1<<UDRE)) );			//Esperar transmision completa
	UDR = data;									//Guardo dato en el registro UDR
	return 0;								
}
int USART_Receive( FILE *stream)
{	
	unsigned char data;
	while ( !(UCSRA & (1<<RXC)) );				//Espera recepcion
	data = UDR;
	//USART_Transmit(data,stream);
	return data;								//Retorno con el dato en el buffer data
}

FILE uart_str = FDEV_SETUP_STREAM(USART_Transmit, USART_Receive, _FDEV_SETUP_RW);

int main(void)
{
	DDRB=0X00;
	PORTB=0X00;
	DDRD=0XFF;
	PORTD=0X00;
	stdout = stdin = &uart_str;
	initUART(MYUBRR);

    while(1)
    {
		printf("H");
		_delay_ms(1000);
        //TODO:: Please write your application code 
    }
}

cuando  mando esa H todo el dato dura unos 30ms creo que eso esta re mal pero uds me guiaran

desde ya muchas gracias!!


----------



## R-Mario (Feb 9, 2012)

Yo veo algunos detalles por ejemplo defines MYUBRR pero en la funcion initUART pones ubrr y bueno ademas no deberias usar stdio solo complica las cosas cuando en realidad es mas facil

//Definimos la frecuencia del micro
#define F_CPU 4000000L
//Y la tasa de transferencia
#define USART_UBBR_VALUE 25


#include <stdint.h>		
#include <avr/io.h>		
#include <avr/delay.h>	

void USART_INIT(void)		//Inicializamos al modulo USART
{
UBRRH = (uint8_t)(USART_UBBR_VALUE>>8);	
UBRRL = (uint8_t)USART_UBBR_VALUE;
UCSRC = (0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);
UCSRB = (1<<RXEN)|(1<<TXEN); 
}

void USART_SendByte(uint8_t u8Data)
{
while((UCSRA&(1<<UDRE)) == 0);
UDR = u8Data; 
}

unsigned char USART_ReceiveByte()
{
while ( !(UCSRA & (1<<RXC)) );
return UDR;
}
int main()
	{
	USART_INIT();
        USART_SendByte('J');
	while(1)
	{
	}

}

Asi tal cual funciona en el atmega8 y es cierto recuerda que el proteus tiene el error de que no invierte la señal que sale por TX por eso en la simulacion le pones un inversor pero en la realidad no se lo pones. Si quieres enviar toda una cadena de texto por la USART pues solo usas un ciclo for y ya

for(int k = 0; k != _Caracteres; k++)
{
USART_SendByte(cadena[k]);
}


----------



## gonpa (Feb 9, 2012)

ese ubrr es el parametro de la funcion, unsigned int ubrr declaras el tipo de parametro que le pasaras a la funcion osea cuando vos calcules MYUBRR la variable ubrr de esa funcion tomara el valor de MYUBRR no tiene nada que ver ademas es correcto, en la hoja de datos esta, y en el attiny2313 me funciona muy bien con el cristal de 11.0592Mhz para cero error pero con un atmega8 a 8MHz no deberia tener problemas tampoco pero en la practica mia me esta dando problemas de velocidad creo. no se si tengo algo mas configurado en los fusebit o en el codigo aunque el codigo es el mismo que use para el attiny2313 =(

alguna idea???


----------

