Una serie de videos en relación a GHDL
Blog cajón desastre (CBTis 44 / TecNM Teziutlán) https://github.com/maigke ( tiene muy poca aportación)
Mostrando entradas con la etiqueta electrónica. Mostrar todas las entradas
Mostrando entradas con la etiqueta electrónica. Mostrar todas las entradas
sábado, 21 de octubre de 2017
martes, 23 de agosto de 2016
Definiendo pines para GAL16V22 de Lattice
Esta prueba la hice desde una box Fedora, instalando el software de Lattice para programar sus dispositivos Lógicos.
En ABEL, la definición de los pines a utilizar cuando se programa una GAL, se hace desde el inicio, sin embargo, en VHDL la cosa no está tan simple, leyendo varios foros, encontre que habria que usar unas sentencias pero no se indica de forma muy genérica.
El código que se presenta a continuación, es un divisor de frecuencias, que tiene dos entradas y una salida, nótese que en este caso, se asigna al pin 6 la entrada de reset para el reloj, y que la declaración de los atributos LOC se hace en el ámbito del instanciamiento de la Entidad que se crea.
Esto solo lo he probado con Lattice y una GAL22V10 simulada en Proteus.
-------------------------------------------------------------------------------
--
-- Company :
-- Engineer: miguel
--
-- Create Date: 04/11/2015 04:50:28
-- Project Name: clk381Hz
-- Module Name: clk381Hz.vhd
-- Description:
--
-- Additional Comments:
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all; -- Para std_logic
use IEEE.numeric_std.all; -- Para unsigned
entity clk381Hz is
Port (
entrada: in STD_LOGIC;
reset : in STD_LOGIC;
salida : out STD_LOGIC
);
attribute LOC: string;
attribute LOC of reset : signal is "6";
end clk381Hz;
architecture arq1 of clk381Hz is
signal temporal: STD_LOGIC;
signal contador: integer range 0 to 250 := 0;
begin
divisor_frecuencia: process (reset, entrada) begin
if (reset = '0') then
temporal <= '0';
contador <= 0;
elsif (entrada 'event and entrada = '1') then
if (contador = 250) then
temporal <= NOT(temporal);
contador <= 0;
else
contador <= contador+1;
end if;
end if;
end process;
salida <= temporal;
end arq1;
En ABEL, la definición de los pines a utilizar cuando se programa una GAL, se hace desde el inicio, sin embargo, en VHDL la cosa no está tan simple, leyendo varios foros, encontre que habria que usar unas sentencias pero no se indica de forma muy genérica.
El código que se presenta a continuación, es un divisor de frecuencias, que tiene dos entradas y una salida, nótese que en este caso, se asigna al pin 6 la entrada de reset para el reloj, y que la declaración de los atributos LOC se hace en el ámbito del instanciamiento de la Entidad que se crea.
Esto solo lo he probado con Lattice y una GAL22V10 simulada en Proteus.
-------------------------------------------------------------------------------
--
-- Company :
-- Engineer: miguel
--
-- Create Date: 04/11/2015 04:50:28
-- Project Name: clk381Hz
-- Module Name: clk381Hz.vhd
-- Description:
--
-- Additional Comments:
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all; -- Para std_logic
use IEEE.numeric_std.all; -- Para unsigned
entity clk381Hz is
Port (
entrada: in STD_LOGIC;
reset : in STD_LOGIC;
salida : out STD_LOGIC
);
attribute LOC: string;
attribute LOC of reset : signal is "6";
end clk381Hz;
architecture arq1 of clk381Hz is
signal temporal: STD_LOGIC;
signal contador: integer range 0 to 250 := 0;
begin
divisor_frecuencia: process (reset, entrada) begin
if (reset = '0') then
temporal <= '0';
contador <= 0;
elsif (entrada 'event and entrada = '1') then
if (contador = 250) then
temporal <= NOT(temporal);
contador <= 0;
else
contador <= contador+1;
end if;
end if;
end process;
salida <= temporal;
end arq1;
sábado, 13 de agosto de 2016
Fritzing Versión 0.9.3no inicia en Fedora 23, 24 y 25 (Actualizado)
Al desempaquetar la nueva versión de Fritzing en Fedora 23, y ejecutar el binario, me indica el siguiente error
Fritzing: error while loading shared libraries: libcrypto.so.1.0.0: cannot open shared object file: No such file or directory
Este error sale si, no tienes instaladas las openssl-devel en tu sistema, sin embargo si lo tengo instalado, el problema surge como indicación de Bug en https://github.com/fritzing/fritzing-app/issues/3245, donde se indica que hay una librería que debe ser borrada de la carpeta lib, en mi caso tuve lo siguiente
lib]$ ls libg*
libgit2.so libgit2.so.0.23.4 libgit2.so.23
Procedi a borrar todo lo indicado en la pagina de issues de github
lib]$ rm libgit2.so*
finalmente, revisar si tenia instalado, ademas de openssl-devel, libgit2-devel
realizado esto, Fritzing vuelve a correr.
***************************************************************************
En Fedora 25 Fritzing requiere de libgit2.so.23 y la Fedora contiene libgit2.so.24 por lo cual no responde de forma adecuada marcando el siguiente error
./Fritzing: error while loading shared libraries: libgit2.so.23: cannot open shared object file: No such file or directory
Para arreglarlo se tiene que crear un enlace simbólico, de este modo Fritzing vuelve a funcionar
$sudo ln -s /lib64/libgit2.so.0.24.6 libgit2.so.23
La fuente original la puedes consultar en:
https://github.com/fritzing/fritzing-app/issues/3289
Fritzing: error while loading shared libraries: libcrypto.so.1.0.0: cannot open shared object file: No such file or directory
Este error sale si, no tienes instaladas las openssl-devel en tu sistema, sin embargo si lo tengo instalado, el problema surge como indicación de Bug en https://github.com/fritzing/fritzing-app/issues/3245, donde se indica que hay una librería que debe ser borrada de la carpeta lib, en mi caso tuve lo siguiente
lib]$ ls libg*
libgit2.so libgit2.so.0.23.4 libgit2.so.23
Procedi a borrar todo lo indicado en la pagina de issues de github
lib]$ rm libgit2.so*
finalmente, revisar si tenia instalado, ademas de openssl-devel, libgit2-devel
realizado esto, Fritzing vuelve a correr.
***************************************************************************
En Fedora 25 Fritzing requiere de libgit2.so.23 y la Fedora contiene libgit2.so.24 por lo cual no responde de forma adecuada marcando el siguiente error
./Fritzing: error while loading shared libraries: libgit2.so.23: cannot open shared object file: No such file or directory
Para arreglarlo se tiene que crear un enlace simbólico, de este modo Fritzing vuelve a funcionar
$sudo ln -s /lib64/libgit2.so.0.24.6 libgit2.so.23
La fuente original la puedes consultar en:
https://github.com/fritzing/fritzing-app/issues/3289
domingo, 17 de noviembre de 2013
Pinguino PIC18F2550 USBBulk y SCILAB con USB - bulk error en Manjaro
Probando Pinguino PIC con Scilab, en la modalidad USB Bulk Transfer, me encontré con el atomo de JOSE PABLO CASTRO VALVERDE, en http://forge.scilab.org.
El scilab si reconoce al Pinguino en modalidad Bulk Transfer pero indica el siguiente error al tratar de enumerar al dispositivo
El scilab si reconoce al Pinguino en modalidad Bulk Transfer pero indica el siguiente error al tratar de enumerar al dispositivo
-->;exec('/home/miguel/Documentos/scilab/usbTst.sce', -1)
Libusb-1.0 Library initialized
device open
endP_success=bulk_set_endpoint(enpIn,enpOut);
!--error 999
bulk_set_endpoint: Wrong size for input argument #1: A scalar expected ????.
at line 29 of exec file called by :
scilab/usbTst.sce', -1
el código que se le carga al Pinguino es el que viene de ejemplo en la version SVN. Espero tener mas avances proximamente.
jueves, 7 de noviembre de 2013
Qucs 0.01.17 en Manjaro
Bien pues sigo probando el uso de Manjaro y pues de momento va muy bien, el desktop es ligero en la PC que tengo, ya es un poco viejita (Gateway con procesador Core 2 con 2GB de RAM y disco de 500GB )
Pues como les comento, estoy probando Qucs y de momento va muy bien y lo mejor es que a diferencia de Fedora 19, esta distro si me está generando el VHDL a partir del diagrama lógico sin problemas, de igual forma Scilab despueś del detalle de ayer, he instalado los atoms de Fuzzy Logic, el complemento Coselica y SIMM para simulación física, y pues las simulaciones han corrido, el problema que tengo es con el IDE de Pinguino X.4 que no me abre, pero ya veré como funciona, aun no he probado la grabación de archivos .hex con AVR y PIC, pero ya está en la pc SDCC y AVR-GCC con el codeblocks.
miércoles, 2 de octubre de 2013
nmap para detectar OS de una LAN
Bueno esta es una entrada muy corta, se trata de poner el comando para Linux donde se usa nmap:
[miguel@dhcppc6 ~]$ sudo nmap -O --osscan-guess --fuzzy 192.168.1.67
Starting Nmap 6.40 ( http://nmap.org ) at 2013-10-02 22:01 CDT
Nmap scan report for 192.168.1.67
Host is up (0.010s latency).
All 1000 scanned ports on 192.168.1.67 are closed
MAC Address: A0:4E:04:9C:29:91 (Nokia)
Too many fingerprints match this host to give specific OS details
Network Distance: 1 hop
OS detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 8.79 seconds
En este caso lo use para ver cual era el SO que está conectado a mi router, es un celular Nokia (de mi hermana)
En cuanto a nmap -O se usa para habilitar la detección de SO
--osscan-guess --fuzzy Se usa para aproximar los resultados del SO cuando el SO que se ve en tu red Local
Etiquetas:
electrónica,
Fedora,
linux
sábado, 21 de septiembre de 2013
Mi archivo 41-microchip.rules Fedora 19 x64
El siguiente es mi archivo 41-microchip.rules, el uso de este archivo es con el fin de conectar los siguientes programadores y ser accedidos como usuario normal a través del software Piklab (http://piklab.sourceforge.net/) :
- Pickit2 clon con firmware 2.x
- ICD2 clon
- Pinguino PIC18F2550
# sudo cp 41-microchip.rules /etc/udev/rules.d/
# sudo usermod -a -G plugdev $USER
#
# Pinguino8 (PIC18F)
ATTR{idVendor}=="04d8", ATTR{idProduct}=="feaa", MODE="0660",GROUP="plugdev"
#
# Pinguino32 (PIC32MX)
ATTR{idVendor}=="04d8", ATTR{idProduct}=="003c", MODE="0660",GROUP="plugdev"
#
# Pickit 2
ATTR{idVendor}=="04d8", ATTR{idProduct}=="0033", MODE="0660",GROUP="plugdev"
#
# Pickit 3
ATTR{idVendor}=="04d8", ATTR{idProduct}=="900a", MODE="0660",GROUP="plugdev"
# ICD2
ATTR{idVendor}=="04d8", ATTR{idProduct}=="8000", MODE="0660",GROUP="plugdev"
# ICD21
ATTR{idVendor}=="04d8", ATTR{idProduct}=="8001", MODE="0660",GROUP="plugdev"
Etiquetas:
electrónica,
Fedora,
linux
martes, 14 de mayo de 2013
Mexican Teensyduino USB en Fedora 18
El siguiente post es para hacer funcionar el clon de Arduino que encontré en la siguiente página en Fedora18
(al final se trabajará con línea de comandos- problemas de dependencias en Fedora18)
No eran problemas de dependencias solo hay que cambiar un poco el archivo .pro, quedando de la siguiente manera
#-------------------------------------------------
#
# Project created by QtCreator 2011-05-31T09:58:34
#
#-------------------------------------------------
QT += core gui
TARGET = easydfu
TEMPLATE = app
SOURCES += main.cpp\
easydfu.cpp
HEADERS += easydfu.h
FORMS += easydfu.ui
RESOURCES += \
icons.qrc
INCLUDEPATH += "/usr/include/QxtCore/"
LIBS += -lQxtCore -lQxtGui
La linea que se cambio fue
INCLUDEPATH+="/usr/include/qxt/QxtCore"
y en el archivo easydfu.h la línea 31 que dice
#include qxt/QxtGui/QxtGlobalShortcut
se cambia por
#include QxtGui/QxtGlobalShortcut
no pongo los signos de mayor que y menor que por que me edita el blogspot ;P
y finalmente el archivo easydfu.cpp se modifican la línea 30 para que el código quede así:
ui->setupUi(this);
//modificado para que lo encuentre el root
programPath = "/usr/local/bin/dfu-programmer";
Cargar Teensy version mexicana en caja Fedora... por maigke
www.comunidadatmel.com
Este clon cuenta con la ventaja de ser un micro con modulo USB integrado, ya que tiene el atmega32u4, el cual de acuerdo al vendedor puede ser programado con sketchs arduino o mediante avr-gcc como un micro normal, pero cuenta con la ventaja de tener un bootloader, el cual le permite grabar al microcontrolador sin necesidad de un programador externo.
Para trabajarlo en modo arduino en Windows, se requiere del software de Arduino, el plug in de Teensyduino y finalmente de Flip. Pero como tengo unas cajas Linux, entonces vamos a echarlo a andar aquí. En otro post les comentaré mi motivación.
Se van a requerir que se descarguen software de los links que a continuación expongo:
http://arduino.cc/en/Main/Software
http://www.pjrc.com/teensy/td_download.html
https://sourceforge.net/projects/dfu-programmer/files/latest/download?source=files
No eran problemas de dependencias solo hay que cambiar un poco el archivo .pro, quedando de la siguiente manera
#-------------------------------------------------
#
# Project created by QtCreator 2011-05-31T09:58:34
#
#-------------------------------------------------
QT += core gui
TARGET = easydfu
TEMPLATE = app
SOURCES += main.cpp\
easydfu.cpp
HEADERS += easydfu.h
FORMS += easydfu.ui
RESOURCES += \
icons.qrc
INCLUDEPATH += "/usr/include/QxtCore/"
LIBS += -lQxtCore -lQxtGui
La linea que se cambio fue
INCLUDEPATH+="/usr/include/qxt/QxtCore"
y en el archivo easydfu.h la línea 31 que dice
#include qxt/QxtGui/QxtGlobalShortcut
se cambia por
#include QxtGui/QxtGlobalShortcut
no pongo los signos de mayor que y menor que por que me edita el blogspot ;P
y finalmente el archivo easydfu.cpp se modifican la línea 30 para que el código quede así:
ui->setupUi(this);
//modificado para que lo encuentre el root
programPath = "/usr/local/bin/dfu-programmer";
En Ubuntu (12.04) mi otra box, pude instalar el siguiente paquete
https://sourceforge.net/projects/dfu-programmer/?source=dlp
Que es un cargador gráfico del .hex generado hacia el micro, mas o menos tipo Flip (ya tambien en Fedora18)
- Se descargan los paquetes de acuerdo al tipo de sistema que tengamos ya sea de 32 o 64 bits.
- Se descomprime el archivo arduino-X.X.X-linuxXX.tgz
- El archivo teensyduino.64bit se le dan permisos de ejecución, solo da clic derecho sobre el icono, selecciona propiedades, da clic en la pestaña Permisos y sobre la casilla "es ejecutable" coloca una paloma mediante un clic.
- Da un doble clic para instalar y saldrá la siguiente pantalla
- Da clic en Next y elige el lugar donde descomprimiste el software de arduino.
-
- Escoge las librerias que te interesa instalar (yo seleccioné todas y di clic en siguiente)
- al dar siguiente, ya nos permitirá instalar el software de Teensy
- Una vez instalado nos aparece la ventana que indica que ya ha terminado la instalación.
- Da clic en el botón Done.
- Ahora ejecuta el software de arduino.
- Y elige la tarjeta Teensy 2.0 del menu Herramientas -> Board ->Teensyduino 2.0
- De esta forma ya podremos generar sketch's para la tarjeta, el siguiente paso consiste en instalar DFU, que es el software a utilizar en lugar de Flip de atmel (Esto es por que flip aun no es compatible con Linux)
- Se descomprime el archivo dfu-programmer-0.6.0
- ingresamos en la carpeta descomprimida
- abrimos una terminal ahi y tecleamos el comando $./bootstrap.sh
- luego $./configure
- $make
- $sudo make install
- La instalacion la realiza en /usr/local/bin, por lo que hay que tener cuidado ya que su no ve este directorio así que para invocar como superusuario debera hacer esto
- $ sudo /usr/local/bin/dfu-programmer atmega32u4 erase por ejemplo
- para programar un sketch realizado
- $sudo /usr/local/bin/dfu-programmer atmega32u4 flash /home/miguel/sketchbook/sketch_may15a/sketch_may15a.cpp.hex
- y para que funcione
- $sudo /usr/local/bin/dfu-programmer atmega32u4 start
- Para la instalación del entorno gráfico (si compila pero no carga correctamente al dfu-programmer :( )
- Se descomprime easydfu_1.0_src.tar.gz
- Entramos a la carpeta
- ejecutamos la orden qmake de la siguiente manera
- qmake-qt4 EasyDFU.pro (recuerda las modificaciones indicadas al inicio del post)
- y luego make
- se debe usar como root o mediante el comando sudo
- asa sas
- Esta es una prueba de que está corriendo el software :)asas
Cargar Teensy version mexicana en caja Fedora... por maigke
Etiquetas:
arduino,
ATmega32u4,
electrónica,
Fedora,
linux
martes, 9 de abril de 2013
Gambas con Pinguino y MySQL
Bien de momento solo voy a escribir que estoy trabajando en un proyecto para la academia a fin de tener una interfaz para el Rally Mecatronico en su versión 5, donde usando MySQL, Gambas2 y Pinguino se vidualizará un tablero de resultados.!!
Aquí una imagen
:D
Aquí una imagen
:D
Etiquetas:
BASIC,
electrónica,
Gambas,
mysql,
pic18f2550
jueves, 28 de marzo de 2013
Para configurar piklab con pickit2
consultado de aquí:
http://www.electronica.robotsperu.org/index.php/microcontroladores/pic-linux-win/5-instalacion-configuracion-pickit-2-piklab
http://www.electronica.robotsperu.org/index.php/microcontroladores/pic-linux-win/5-instalacion-configuracion-pickit-2-piklab
Etiquetas:
electrónica,
linux,
teziutlan
martes, 26 de marzo de 2013
Máquinas de estados finitas en C
La siguiente herramienta les permitirá construir una máquina de estados finitos
http://qfsm.sourceforge.net/download.html
Las dependencias son
Graphviz ()
cmake
make
para instalar desde las fuentes usa la version 0.52 ya que la actual en Fedora 18 indica un error
/usr/include/string.h:66:77: error: declaration of ‘int memcmp(const void*, const void*, size_t) throw ()’ has a different exception specifier
/usr/include/graphviz/cdt.h:242:12: error: from previous declaration ‘int memcmp(const void*, const void*, size_t)’
El cual en el sourceForge, el autor indica lo siguiente:
http://qfsm.sourceforge.net/download.html
Las dependencias son
Graphviz ()
cmake
make
para instalar desde las fuentes usa la version 0.52 ya que la actual en Fedora 18 indica un error
/usr/include/string.h:66:77: error: declaration of ‘int memcmp(const void*, const void*, size_t) throw ()’ has a different exception specifier
/usr/include/graphviz/cdt.h:242:12: error: from previous declaration ‘int memcmp(const void*, const void*, size_t)’
El cual en el sourceForge, el autor indica lo siguiente:
I cannot reproduce the problem with Linux 3.2.0 / Ubuntu 12.04 / Qt 4.8.1 /
graphviz 2.26.3.
You seem to have graphviz 2.28 installed, and it seems that the problem
comes from an incompatibility between graphviz 2.28 and Qt.
I will do some further investigation.
Stefan
Y en mi caso, tengo Fedora 18, con graphviz 2.28 , que de acuerdo al autor, causa el problema indicado.
graphviz 2.26.3.
You seem to have graphviz 2.28 installed, and it seems that the problem
comes from an incompatibility between graphviz 2.28 and Qt.
I will do some further investigation.
Stefan
Y en mi caso, tengo Fedora 18, con graphviz 2.28 , que de acuerdo al autor, causa el problema indicado.
Etiquetas:
electrónica,
linux,
teziutlan
error semántico en eclipse AVR
Cuando se tiene una instalación fresca de eclipse con el plug-in de avr, es posible compilar un programa aunque en la ventana de problemas coloca un error al no identificar los defines de los puertos
Descripción Información Ruta Ubicación Type
Symbol 'PB3' could not be resolved main.c /mo línea 27 Semantic Error
aunque el programa incluya al archivo io.h
Otra opción que se lee en el foro http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=902018 es entrar a las propiedades del proyecto y en la opción Target Hardware del menú AVR
seleccionar de nuevo el microcontrolador a utilizar y posteriormente dar clic derecho sobre el nombre del proyecto.
Una vez ahí seleccionar índices y luego la opción rebuild.
Descripción Información Ruta Ubicación Type
Symbol 'PB3' could not be resolved main.c /mo línea 27 Semantic Error
aunque el programa incluya al archivo io.h
#includeUna forma de resolver este problema es medinte la inclusión del archivo .h del correspondiente microcontrolador (en este caso el//#include #define F_CPU 1000000UL #include #define clearbit(sfr,bit) _SFR_BYTE(sfr)&=~_BV(bit) #define setbit(sfr,bit) _SFR_BYTE(sfr)|=_BV(bit) #define start PINB0 #define pstart PINB #define stop PINB1 #define pstop PINB #include "help.h" int main(void) { //unsigned char flag = hola; config(); while(1) { if(bit_is_set(pstart,start) && bit_is_set(pstop,stop)) { clearbit(PORTB, PB3); } else { setbit(PORTB,PB3); } } return 0; }
#includeque se encuentra comentado).
Otra opción que se lee en el foro http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=902018 es entrar a las propiedades del proyecto y en la opción Target Hardware del menú AVR
seleccionar de nuevo el microcontrolador a utilizar y posteriormente dar clic derecho sobre el nombre del proyecto.
Una vez ahí seleccionar índices y luego la opción rebuild.
Etiquetas:
electrónica,
linux,
teziutlan
miércoles, 26 de diciembre de 2012
Winavr- display 7 segmentos multiplexados - libreria alfa
Esta es una libreria en alfa, ya es funcional y admite cierta flexibilidad en el uso de pines, pero requiere de mucho manoseo por parte del usuario, espero comentarios, en el post se encuentra el diagrama con las indicaciones pertinentes.
Winavr- display 7 segmentos multiplexados - libreria alfa
Winavr- display 7 segmentos multiplexados - libreria alfa
Etiquetas:
electrónica,
linux,
teziutlan
lunes, 24 de diciembre de 2012
Libreria LCD 20 x 4 Flexible 4 bits SDCC PIC18F2550
Este enlace lleva al codigo fuente de como hacer la interfaz entre una LCD y un micro PIC18f2550 mediante 4 bits definidos por el usuario, no importa el orden de conexion, esto es muy util cuando
se requiere de hacer ajustes en la placa donde se montaría el circuito.
Libreria LCD 20 x 4 Flexible 4 bits SDCC PIC18F2550
se requiere de hacer ajustes en la placa donde se montaría el circuito.
Libreria LCD 20 x 4 Flexible 4 bits SDCC PIC18F2550
Etiquetas:
electrónica,
linux,
teziutlan
Libreria LCD 20x 4 Flexible 3 bits SDCC PIC18F2550
Esta es una libreria que se utiliza para comunicar un micro pic18f2550 con una pantalla LCD
alfanumerica de 2 caracteres por 4 lineas:
Libreria LCD 20x 4 Flexible 3 bits SDCC PIC18F2550
alfanumerica de 2 caracteres por 4 lineas:
Libreria LCD 20x 4 Flexible 3 bits SDCC PIC18F2550
Etiquetas:
electrónica,
linux,
teziutlan
miércoles, 14 de diciembre de 2011
Proyecto para IGL UNAM
Este es parte del proyecto que estamos realizando en el ITST.
Créditos
Ing. Miguel Montiel Mtz -- Parte Electrónica
M.C. Julio César Camargo Santos -- Parte Mecánica
Créditos
Ing. Miguel Montiel Mtz -- Parte Electrónica
M.C. Julio César Camargo Santos -- Parte Mecánica
Etiquetas:
electrónica,
linux,
pic16f819,
pic18f2550,
sdcc
PIC18F2250 y timer 1 una propuesta para configurarlo.
bueno aquí está parte del trabajo que realicé en el año. Se esperan comentarios.
http://www.itsteziutlan.edu.mx/index.php?option=com_content&view=article&id=715:propuesta-para-la-programacion-basica-del-temporizador-1-del-microcontrolador-pic18f2550-con-el-compilador-sdcc&catid=27:artlos&Itemid=288
http://www.itsteziutlan.edu.mx/index.php?option=com_content&view=article&id=714:propuesta-para-la-configuracion-basica-del-temporizador-1-del-microcontrolador-pic18f2550&catid=27:artlos&Itemid=288
http://www.itsteziutlan.edu.mx/index.php?option=com_content&view=article&id=715:propuesta-para-la-programacion-basica-del-temporizador-1-del-microcontrolador-pic18f2550-con-el-compilador-sdcc&catid=27:artlos&Itemid=288
http://www.itsteziutlan.edu.mx/index.php?option=com_content&view=article&id=714:propuesta-para-la-configuracion-basica-del-temporizador-1-del-microcontrolador-pic18f2550&catid=27:artlos&Itemid=288
Etiquetas:
electrónica,
linux,
maigke,
mexico,
micros,
montiel,
pic18f2550,
pics,
piklab,
sdcc,
tec,
temporizado,
teziutlan
lunes, 31 de enero de 2011
Algo que escribí
Bueno aquí dejo algo que escribí en la escuela, no esta muy bien redactado, pero la idea fundamental es dar a conocer la existencia de las herramientas libres para la programación de microcontroladores PIC.
Echenle un ojito y espero sus comentarios
LINK
http://www.itsteziutlan.edu.mx/index.php?option=com_content&view=article&id=597:herramientas-libres-para-la-programacion-de-microcontroladores-pic&catid=27:artlos&Itemid=288
Echenle un ojito y espero sus comentarios
LINK
http://www.itsteziutlan.edu.mx/index.php?option=com_content&view=article&id=597:herramientas-libres-para-la-programacion-de-microcontroladores-pic&catid=27:artlos&Itemid=288
miércoles, 29 de diciembre de 2010
Control de Servomotores con SDCC- Original de RedPIC Parte 2
Bueno después de mucho trabajar, por fin creo que ya funca esta versión del programa realizado por Redpic, pero en SDCC, como características tiene las siguientes:
* Comunicación por el puerto RS232 a 57600bps, pero puede aumentarse a 115200bps
* La forma de control de los servos es secuencial, lo que no permite mover dos servos de forma simultánea.
* El formato de instrucción es [servo][valor en grados][velocidad]
-Para servo usamos un byte char [a|b|c|d|e|f]
-Para valor en grados usamos tres bytes ejemplos [090] [001] [175] 90°, 1°, y 175° respectivamente
* Envia códigos de error cuando son suministrados los datos por el puerto serial
Códigos de mensajes de error
0 -- Buffer lleno Se han enviado demasiados caracteres
1 -- turnPLus error no puedo mover servo seleccionado
2 -- turnMinus error no puedo mover servo seleccionado
3 -- commandProcess error o puedo elegir ese servo
Cuando el proceso termina satisfactoriamente se manda la cadena "ok"
Para definir los servos a mover, usamos las siguientes macros definidas al inicio del código
//Definiciones de servos
#define SERVO1 LATBbits.LATB0
#define SERVO2 LATBbits.LATB1
#define SERVO3 LATBbits.LATB2
#define SERVO4 LATBbits.LATB3
#define SERVO5 LATBbits.LATB4
#define SERVO6 LATBbits.LATB5
#define SERVO7 LATBbits.LATB6
#define SERVO8 LATBbits.LATB7
#define CSERVO1 TRISBbits.TRISB0
#define CSERVO2 TRISBbits.TRISB1
#define CSERVO3 TRISBbits.TRISB2
#define CSERVO4 TRISBbits.TRISB3
#define CSERVO5 TRISBbits.TRISB4
#define CSERVO6 TRISBbits.TRISB5
#define CSERVO7 TRISBbits.TRISB6
#define CSERVO8 TRISBbits.TRISB7
Una característica mas, es que no es necesario usar los 8 pines como salida, sino que podemos elegir mediante el "bit"
boolean SERVO1_ON = true;
boolean SERVO2_ON = true;
boolean SERVO3_ON = true;
boolean SERVO4_ON = true;
boolean SERVO5_ON = true;
boolean SERVO6_ON = true;
boolean SERVO7_ON = true;
boolean SERVO8_ON = true;
Si necesitamos usar dos servos, un servo o los 8, como gustes Very Happy, (Esto tambien es original del código de RedPIC)
* Comunicación por el puerto RS232 a 57600bps, pero puede aumentarse a 115200bps
* La forma de control de los servos es secuencial, lo que no permite mover dos servos de forma simultánea.
* El formato de instrucción es [servo][valor en grados][velocidad]
-Para servo usamos un byte char [a|b|c|d|e|f]
-Para valor en grados usamos tres bytes ejemplos [090] [001] [175] 90°, 1°, y 175° respectivamente
* Envia códigos de error cuando son suministrados los datos por el puerto serial
Códigos de mensajes de error
0 -- Buffer lleno Se han enviado demasiados caracteres
1 -- turnPLus error no puedo mover servo seleccionado
2 -- turnMinus error no puedo mover servo seleccionado
3 -- commandProcess error o puedo elegir ese servo
Cuando el proceso termina satisfactoriamente se manda la cadena "ok"
Para definir los servos a mover, usamos las siguientes macros definidas al inicio del código
//Definiciones de servos
#define SERVO1 LATBbits.LATB0
#define SERVO2 LATBbits.LATB1
#define SERVO3 LATBbits.LATB2
#define SERVO4 LATBbits.LATB3
#define SERVO5 LATBbits.LATB4
#define SERVO6 LATBbits.LATB5
#define SERVO7 LATBbits.LATB6
#define SERVO8 LATBbits.LATB7
#define CSERVO1 TRISBbits.TRISB0
#define CSERVO2 TRISBbits.TRISB1
#define CSERVO3 TRISBbits.TRISB2
#define CSERVO4 TRISBbits.TRISB3
#define CSERVO5 TRISBbits.TRISB4
#define CSERVO6 TRISBbits.TRISB5
#define CSERVO7 TRISBbits.TRISB6
#define CSERVO8 TRISBbits.TRISB7
Una característica mas, es que no es necesario usar los 8 pines como salida, sino que podemos elegir mediante el "bit"
boolean SERVO1_ON = true;
boolean SERVO2_ON = true;
boolean SERVO3_ON = true;
boolean SERVO4_ON = true;
boolean SERVO5_ON = true;
boolean SERVO6_ON = true;
boolean SERVO7_ON = true;
boolean SERVO8_ON = true;
Si necesitamos usar dos servos, un servo o los 8, como gustes Very Happy, (Esto tambien es original del código de RedPIC)
/* ----------------------------------------------------------------------- */
/* Plantilla generada por Piklab */
/*
La configuracion del micro nos permite trabajar un con XT de 20MHZ
y pero usar el PLL con el propósito de alcanzar los 12MIPS
Códigos de mensajes de error
0 -- Buffer lleno Se han enviado demasiados caracteres
1 -- turnPLus error no puedo mover servo seleccionado
2 -- turnMinus error no puedo mover servo seleccionado
3 -- commandProcess error o puedo elegir ese servo
ok -- Proceso terminado correctamente
*/
#include <pic18f2550.h>
#include <delay.h>
#include <uart18f2550.c>
#include <stdlib.h>
#include <string.h>
/* ----------------------------------------------------------------------- */
/* Bits de configuración: adapte los parámetros a su necesidad */
code char at __CONFIG1L CONFIG1L = _PLLDIV_DIVIDE_BY_5__20MHZ_INPUT__1L & _CPUDIV__OSC1_OSC2_SRC___1__96MHZ_PLL_SRC___2__1L & _USBPLL_CLOCK_SRC_FROM_96MHZ_PLL_2_1L;
code char at __CONFIG1H CONFIG1H = _OSC_HS__HS_PLL__USB_HS_1H & _FCMEN_ON_1H & _IESO_ON_1H;
code char at __CONFIG2L CONFIG2L = _PUT_ON_2L & _BODEN_ON_2L & _BODENV_4_2V_2L & _VREGEN_ON_2L;
code char at __CONFIG2H CONFIG2H = _WDT_DISABLED_CONTROLLED_2H & _WDTPS_1_32768_2H;
code char at __CONFIG3H CONFIG3H = _CCP2MUX_RC1_3H & _PBADEN_PORTB_4_0__CONFIGURED_AS_DIGITAL_I_O_ON_RESET_3H & _LPT1OSC_ON_3H & _MCLRE_MCLR_OFF_RE3_ON_3H;
code char at __CONFIG4L CONFIG4L = _STVR_ON_4L & _LVP_OFF_4L & _ENHCPU_OFF_4L & _BACKBUG_OFF_4L;
code char at __CONFIG5L CONFIG5L = _CP_0_OFF_5L & _CP_1_OFF_5L & _CP_2_OFF_5L & _CP_3_OFF_5L;
code char at __CONFIG5H CONFIG5H = _CPB_OFF_5H;
code char at __CONFIG6L CONFIG6L = _WRT_0_OFF_6L & _WRT_1_OFF_6L & _WRT_2_OFF_6L & _WRT_3_OFF_6L;
code char at __CONFIG6H CONFIG6H = _WRTC_OFF_6H & _WRTB_OFF_6H;
code char at __CONFIG7L CONFIG7L = _EBTR_0_OFF_7L & _EBTR_1_OFF_7L & _EBTR_2_OFF_7L & _EBTR_3_OFF_7L;
code char at __CONFIG7H CONFIG7H = _EBTRB_OFF_7H;
//Definiciones de servos
#define SERVO1 LATBbits.LATB0
#define SERVO2 LATBbits.LATB1
#define SERVO3 LATBbits.LATB2
#define SERVO4 LATBbits.LATB3
#define SERVO5 LATBbits.LATB4
#define SERVO6 LATBbits.LATB5
#define SERVO7 LATBbits.LATB6
#define SERVO8 LATBbits.LATB7
#define CSERVO1 TRISBbits.TRISB0
#define CSERVO2 TRISBbits.TRISB1
#define CSERVO3 TRISBbits.TRISB2
#define CSERVO4 TRISBbits.TRISB3
#define CSERVO5 TRISBbits.TRISB4
#define CSERVO6 TRISBbits.TRISB5
#define CSERVO7 TRISBbits.TRISB6
#define CSERVO8 TRISBbits.TRISB7
typedef enum{false = 0, true = 1} boolean; //para definir variables booleanas
//boolean tuza = true; este es solo un ejemplo
//Constantes para la definición de ventanas
const unsigned Ticks4WindowH = 0x75;
const unsigned Ticks4WindowL = 0x2F;
const unsigned Ticks4CenterH = 0x46;
const unsigned Ticks4CenterL = 0x4F;
const unsigned Ticks4MinimumH = 0x17;
const unsigned Ticks4MinimumL = 0x6F;
const unsigned Ticks4MaximumH = 0x6B;
const unsigned Ticks4MaximumL = 0xCF;
static unsigned int Ticks4NextInterruptH = 0xCF;
static unsigned int Ticks4NextInterruptL = 0x2C;
const unsigned Ticks4Window = 0x752F;
const unsigned Ticks4Minimum = 0x176F;
const unsigned Ticks4Center = 0x464F;
const unsigned Ticks4Maximum = 0x6BCF;
static unsigned int Ticks4NextInterrupt = 0xCF2C;
static unsigned int Servo_PWM[8];
static unsigned int tempom=0x0000;
static unsigned int tempo=0x0000;
static unsigned int tempol;
static unsigned int tempoh;
static unsigned int Servo_PWMH[8];
static unsigned int Servo_PWML[8];
static unsigned short Servo_Idx = 0;
boolean SERVO1_ON = true;
boolean SERVO2_ON = true;
boolean SERVO3_ON = true;
boolean SERVO4_ON = true;
boolean SERVO5_ON = true;
boolean SERVO6_ON = true;
boolean SERVO7_ON = true;
boolean SERVO8_ON = true;
//definicion de teclas
#define INTRO 0x0D
#define RETROCESO 0x08
#define ESCAPE 0x1B
boolean flag_Phase;
unsigned short j=0xFF;
unsigned int posI;
/*Seccion para la comunicacion en serial*/
#define lenbuff 10
unsigned char xbuff=0x00;
unsigned char cbuff[lenbuff];
char rcvchar=0x00;
boolean flagcommand = false;
//variables para timers
unsigned char CounterA;
unsigned char CounterB;
//Prototipos
void init_board(void);
void EnableTimer1Interrupt(void);
void Tmr1Carga(unsigned char high, unsigned char low);
void initBuff(void);
void add2cbuff(unsigned char c);
void echosel(char c);
void command_process(void);
void delay_ms(int milis);
void delay_us(int milis);
unsigned int SelectServo(unsigned char Servo);
void turnPlus(int vueltas, unsigned char vel, unsigned char Servo);
void turnMinus(int vueltas, unsigned char vel,unsigned char Servo);
//Sección de interrupciones
static void isr_Tmr1() interrupt 1 //Esta es una interrupcion de alta prioridad
{
PIE1bits.RCIE=0; //deshabilitamos la interrupcion del puerto serie
if(flag_Phase == 1)
{
if(Servo_Idx == 0 && SERVO1_ON) {SERVO1 = 1;}
if(Servo_Idx == 1 && SERVO2_ON) {SERVO2 = 1;}
if(Servo_Idx == 2 && SERVO3_ON) {SERVO3 = 1;}
if(Servo_Idx == 3 && SERVO4_ON) {SERVO4 = 1;}
if(Servo_Idx == 4 && SERVO5_ON) {SERVO5 = 1;}
if(Servo_Idx == 5 && SERVO6_ON) {SERVO6 = 1;}
if(Servo_Idx == 6 && SERVO7_ON) {SERVO7 = 1;}
if(Servo_Idx == 7 && SERVO8_ON) {SERVO8 = 1;}
Ticks4NextInterruptH = 0xFF - Servo_PWMH[Servo_Idx];
Ticks4NextInterruptL = 0xFF - Servo_PWML[Servo_Idx];
Tmr1Carga(Ticks4NextInterruptH,Ticks4NextInterruptL);
}
if(flag_Phase == 0)
{
if(Servo_Idx == 0 && SERVO1_ON) {SERVO1 = 0;}
if(Servo_Idx == 1 && SERVO2_ON) {SERVO2 = 0;}
if(Servo_Idx == 2 && SERVO3_ON) {SERVO3 = 0;}
if(Servo_Idx == 3 && SERVO4_ON) {SERVO4 = 0;}
if(Servo_Idx == 4 && SERVO5_ON) {SERVO5 = 0;}
if(Servo_Idx == 5 && SERVO6_ON) {SERVO6 = 0;}
if(Servo_Idx == 6 && SERVO7_ON) {SERVO7 = 0;}
if(Servo_Idx == 7 && SERVO8_ON) {SERVO8 = 0;}
Ticks4NextInterruptH = 0xFF - Ticks4WindowH;
Ticks4NextInterruptL = 0xFF - Ticks4WindowL;
if(Ticks4NextInterruptL + Servo_PWML[Servo_Idx] > 0xFF)
{
Ticks4NextInterruptL = Ticks4NextInterruptL + Servo_PWML[Servo_Idx];
Ticks4NextInterruptH = Ticks4NextInterruptH + Servo_PWMH[Servo_Idx] + 1;
}
else
{
Ticks4NextInterruptL = Ticks4NextInterruptL + Servo_PWML[Servo_Idx];
Ticks4NextInterruptH = Ticks4NextInterruptH + Servo_PWMH[Servo_Idx];
}
Tmr1Carga(Ticks4NextInterruptH, Ticks4NextInterruptL);
if(++Servo_Idx > 7 ) Servo_Idx = 0;
}
if(++flag_Phase > 1) flag_Phase = 0;
//Esta instruccion se esta ejecutando cada 13ms con un xtal de 20MHz
LATBbits.LATB7^=1; //complementamos el valor del bit RB7
PIR1bits.TMR1IF=0; //limpiamos la bandera de interrupcion
PIE1bits.RCIE=1; //habilitamos la interrupcion del puerto serie
}
static void isr_Serial() interrupt 2 //Esta es una interrupcion de baja prioridad
{
PIR1bits.RCIF=0;
rcvchar=RCREG;
add2cbuff(rcvchar);
echosel(rcvchar);
}
//Funcion Principal
void main() {
//declaracion de variables
int i=0;
int button_down=1;
int valTimer=0;
RCONbits.IPEN=1; //interrupciones por prioridad habilitadas
init_board();
Print_str("Dispositivo inicializado");
Printf(INTRO);
Print_str("PIC18F2550 en SDCC");
Printf(INTRO);
delay_ms(500); //tiempo de espera
initBuff();
for (i=0;i<9;i++)
{
Servo_PWMH[i] = Ticks4CenterH;
Servo_PWML[i] = Ticks4CenterL;
}
EnableTimer1Interrupt();
tempo = Ticks4Center;
tempoh = tempo & 0xFF00;
tempol = tempo & 0x00FF;
Tmr1Carga(tempoh, tempol);
posI = Ticks4Center;
while (true)
{
if(flagcommand) //si ya presionaste enter
{
command_process();
}
}
}
void init_board(void) {
flagcommand= false;
ADCON1=0x7; // PORTA used for digital I/O
TRISAbits.TRISA4=true; // configure PORTA4 for input (pushbutton)
/* Configuramos las salidas de los servomotores*/
CSERVO1 = false;
CSERVO2 = false;
CSERVO3 = false;
CSERVO4 = false;
CSERVO5 = false;
CSERVO6 = false;
CSERVO7 = false;
CSERVO8 = false;
//Configuramos la comunicacion serial --rutina de jean Pierre Mandon
setup_UART(B57600);
}
void EnableTimer1Interrupt(void)
{
T1CON=1; //Timer1 preescaler 1 interno, carga de 8 bits
PIE1bits.TMR1IE=1;
INTCONbits.PEIE=1;
INTCONbits.GIE=1;
}
void Tmr1Carga(unsigned char high, unsigned char low)
{
TMR1H=high;
TMR1L=low;
}
//Funcion de vaciado del buffer
void initBuff(void){
int i;
for (i=0; i< lenbuff;i++){
cbuff[i]=0x0;
}xbuff=0x00;
}
//agrega un caracter mas al buffer, o realiza un acción
void add2cbuff(unsigned char c)
{
if(xbuff<lenbuff){ //Añade caracteres al buffer mientras no se llene el buffer
switch(c){
case INTRO: //Enter --> Habilita flag para procesar comando
flagcommand=true;
break;
case RETROCESO: //BackSpace --> Borra del buffer el ultimo caracter insertado
if(xbuff>0) cbuff[--xbuff]=0x00;
break;
case ESCAPE: //ESC --> Borra todo el buffer
initBuff();
break;
default: //añade caracter al buffer recibido
cbuff[xbuff++]=c;
}
}
else{
initBuff();//Si el buffer esta lleno, vacialo
Print_str("0"); //Envia mensaje de que el buffer esta lleno Error 0
Printf(INTRO);
}
}
//Solo imprime los caracteres imprimibles
void echosel(char c)
{
switch(c){
case 0x0D: //Si presionamos la tecla intro
Printf(INTRO);
break;
case 0x08: //Si presionamos la tecla BackSpace
Printf(RETROCESO);
break;
case 0x1B: //Si presionamos la tecla ESC
Printf(ESCAPE);
break;
default:
Printf(c); //Echo de cualquier otro caracter
}
}
/*
El formato de los comandos es el siguiente:
[a...f] [123] [xx]
servo posicion velocidad
primer byte un caracter alfabético de entre a y e que define al servo
tres bytes para definir la posicion del servo
dos bytes para definir la velocidad de movimiento del servo
a12301 {enter}
mueve el servo 1 a 123 grados de la posicion de origen a la velocidad 01
*/
void command_process()
{
int i=0;
char DerIzq= 1; //bandera para saber si va a 180 o a 0 grados
// DerIzq = 1 Indicará que vamos de 0 a 180 por tanto suma
// DerIzq = 0 Indicará que vamos de 180 a 0 por tanto resta
unsigned char cmd[lenbuff]; //comando tecleado
unsigned char servo[2];
unsigned char pos[4]; //para almacenar las posiciones
unsigned char posicion;
unsigned char velocidad[4]; //para almacenar los incrementos
unsigned char vel;
unsigned int posF; //Es posible que estos valores los tengas que dividir
unsigned int vueltas;
flagcommand=false;
//Recibe el nombre del servo a mover
strcpy(cmd,cbuff);
strncpy(servo,cmd,1);
//guarda la posicion del servo
strcpy(cmd,cbuff);
for(i=1;i<4;i++){
pos[i-1]= cmd[i];
}
posicion = atoi(pos);
//guarda la velocidad a la que se moverá el servo
strcpy(cmd,cbuff);
for(i=4;i<7;i++)
{
velocidad[i-4]=cmd[i];
}
vel = atoi(velocidad);
tempo = 0;
tempoh=0;
tempol=0;
switch(servo[0]){
case 'a':
posI=SelectServo(0);
break;
case 'b':
posI=SelectServo(1);
break;
case 'c':
posI=SelectServo(2);
break;
case 'd':
posI=SelectServo(3);
break;
case 'e':
posI=SelectServo(4);
break;
case 'f':
posI=SelectServo(5);
break;
default:
Print_str("3"); //Error 3 opcion elegida no válida
Printf(INTRO);
break;
}
posF= 106.66 * posicion + 8399;
if(posF>posI){
vueltas = posF - posI;
vueltas = vueltas / vel;
DerIzq = 1;
}
else
{
vueltas = posI - posF;
vueltas = vueltas/ vel;
DerIzq = 0;
}
/********************************************************/
/*
Debe de leerse el valor que tiene del servo desde el array
Žpara determinar el valor inicial y no unicamente dejarlo
como valor final. esto causa el eeror de que al mover
multiples motores con una unica variable se moveran en conse-
cuencia del anterior
*/
// posI = posF; Esto no es correcto
if(DerIzq)
{
switch(servo[0])
{
case 'a': //mueve al servo uno en incrementos de vel hasta llegar a vueltas
turnPlus(vueltas, vel, 0);
break;
case 'b': //mueve al servo dos en incrementos de vel hasta llegar a vueltas
turnPlus(vueltas, vel, 1);
break;
case 'c':
turnPlus(vueltas, vel, 2);
break;
case 'd':
turnPlus(vueltas, vel, 3);
break;
case 'e':
turnPlus(vueltas, vel, 4);
break;
default:
Print_str("1"); Printf(INTRO); //Error 1 turnPlusError
}
}
else{
switch(servo[0])
{
case 'a': //mueve al servo uno en incrementos de vel hasta llegar a vueltas
turnMinus(vueltas,vel,0);
break;
case 'b': //mueve al servo dos en incrementos de vel hasta llegar a vueltas
turnMinus(vueltas,vel,1);
break;
case 'c':
turnMinus(vueltas,vel,2);
break;
case 'd':
turnMinus(vueltas,vel,3);
break;
case 'e':
turnMinus(vueltas,vel,4);
break;
default:
Print_str("2");Printf(INTRO); // error 2 turnMinus Error
}
}
initBuff();
Print_str("ok");Printf(INTRO);
}
void delay_ms(int milis){
delay1ktcy(10*milis);
}
void delay_us(int milis){
delay10tcy(1*milis);
}
unsigned int SelectServo(unsigned char Servo)
{
tempoh = Servo_PWMH[Servo];
tempo = tempoh << 8;
return (tempo | Servo_PWML[Servo]);
}
void turnPlus(int vueltas, unsigned char vel, unsigned char Servo)
{
int i=0;
for(i=0;i<vueltas;i++)
{
tempoh = Servo_PWMH[Servo];
tempoh = tempoh << 8;
tempo = tempoh | Servo_PWML[Servo];
tempo += vel;
Servo_PWML[Servo] = tempo & 0x00FF;
tempoh = tempo & 0xFF00;
tempoh = tempoh >> 8;
Servo_PWMH[Servo] = tempoh;
delay_us(100);
}
}
void turnMinus(int vueltas, unsigned char vel, unsigned char Servo)
{
int i=0;
for(i=0;i<vueltas;i++)
{
tempoh = Servo_PWMH[Servo];
tempoh = tempoh << 8;
tempo = tempoh | Servo_PWML[Servo];
tempo -= vel;
Servo_PWML[Servo] = tempo & 0x00FF;
tempoh = tempo & 0xFF00;
tempoh = tempoh >> 8;
Servo_PWMH[Servo] = tempoh;
delay_us(100);
}
}
Etiquetas:
electrónica,
linux,
sdcc,
Serial,
servo,
servomotor
Control de Servomotores con SDCC- Original de RedPIC Parte 1
Control de 8 servos de RC por puerto serie -- Original de RedPIC traducido a SDCC
Mensaje maigke el Vie 17 Sep 2010 - 9:32
Buenas noches a todos (Aquí en Mx es de madrugada)
Bien en esta ocasion les presento un codigo que es original de RedPIc, y que gracias a la lógica que el presenta en su sitio, he aprendido bastante. Pues bien, aqui esta el código que el nos presenta para controlar 8 servomotores con una sola interrupcion del timer1 a 16 bits, pero con las siguientes modificaciones:
-- El pic es un 18F2550
-- El lenguaje claro que es SDCC y pues así lo hace libre esto.
-- El oscilador es a 20MHz, pero basado en el proyecto Pinguino se establece que el micro trabaje a 12MIPS.
-- Tome algunos ejemplos de como trabaja el proyecto Pinguino de Jean - Pierre Mandon.
-- Aun el micro no entiende lo que le mandes por el puerto paralelo serial (andaba medio dormido). cyclops pero ya mero
sin mas preambulos, les muestro el código, que digamoslo así, es casí una copia fiel, pero con sus bueno retoques, algo importante, no se la causa del por que el SDCC no trabaja bien con las operaciones de 16bits, así que tuve que hacer algunos ajustes, así que tuve que gastar aun mas recursos de los que ya de por si SDCC requiere. posterior les presento algunas pantallas.
Espero sus notas y comentarios:, por cierto este post, se puede ligar al de GAMBAS + pic16f628 + puerto serial. Wink
Y esta es la rutina de comunicacion serial de Jean Pierre que use
// UART Library for PIC 18F2550
// SDCC version / small device c compiler
// written by Jean-Pierre MANDON 2008 jp.mandon@free.fr
// www.pictec.org
/*
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding!
*/
// this program is intended for an oscillator frequency of 20 Mhz
// SPBRG value for FOSC 20 Mhz
#define B300 1,0,0x27,0x0F
#define B1200 1,0,0x09,0xC3
#define B2400 1,0,0x04,0xE1
#define B4800 1,0,0x02,0x70
#define B9600 0,0,0x00,0x4D
#define B19200 0,0,0x00,0x26
#define B57600 1,1,0x00,0xCF
#define B115200 1,1,0x00,0x67
// local definition UART.C
#define BUFFER 128 // rx buffer length
char rx[BUFFER]; // this is the buffer
unsigned char wpointer,rpointer; // write and read pointer
#define charreceived (wpointer!=rpointer)
#define SERIAL
typedef struct
{
unsigned int
hhigh4:4,
hlow4:4,
lhigh4:4,
llow4:4;
} bitfield;
// setup PIC UART
void setup_UART(unsigned char brg16,unsigned char brgh,unsigned char highbyte,unsigned char lowbyte)
{
TXSTAbits.BRGH=brgh&1; // set BRGH bit
BAUDCONbits.BRG16=brg16&1; // set 16 bits SPBRG
SPBRGH=highbyte; // set UART speed SPBRGH
SPBRG=lowbyte; // set UART speed SPBRGL
RCSTA=0x90; // set RCEN and SPEN
BAUDCONbits.RCIDL=1; // set receive active
PIE1bits.RCIE=1; // enable interrupt on RX
INTCONbits.PEIE=1; // enable peripheral interrupts
IPR1bits.RCIP=0; // define low priority for RX interrupt
wpointer=1; // initialize write pointer
rpointer=1; // initialize read pointer
TXSTAbits.TXEN=1; // enable TX
INTCONbits.GIE=1;
}
// UART write char
void Printf(unsigned char caractere)
{
while (!TXSTAbits.TRMT);
TXREG=caractere; // yes, send char
}
// rxint is called by interruption service routine
void rxint(void)
{
char caractere;
unsigned char newwp;
PIR1bits.RCIF=0; // clear RX interrupt flag
caractere=RCREG; // take received char
if (wpointer!=BUFFER-1) // if not last place in buffer
newwp=wpointer+1; // place=place+1
else
newwp=1; // else place=1
if (rpointer!=newwp) // if read pointer!=write pointer
rx[wpointer++]=caractere; // store received char
if (wpointer==BUFFER) // if write pointer=length buffer
wpointer=1; // write pointer = 1
}
// get char
unsigned char getch()
{
unsigned char caractere=0;
if (charreceived)
{
caractere=rx[rpointer++];
if (rpointer==BUFFER)
rpointer=1;
}
return(caractere);
}
// clear rx buffer
void clear_buffer(void) {
wpointer=1;
rpointer=1;
}
// write a string on the UART
void Print_str(const char* text)
{
unsigned char i=0;
while ( text[i] != 0 )
Printf( text[i++] );
}
// convert 16 bits binary value to DEC and send it on the UART
void Print_dec(unsigned int valeur)
{
unsigned char result;
unsigned char zero=1;
result=valeur/10000;
if (result!=0) {
Printf(result+0x30);
zero=0;
}
valeur=valeur%10000;
result=valeur/1000;
if (result!=0) {
Printf(result+0x30);
zero=0;
}
else if (zero==0) Printf('0');
valeur=valeur%1000;
result=valeur/100;
if (result!=0) {
Printf(result+0x30);
zero=0;
}
else if (zero==0) Printf('0');
valeur=valeur%100;
result=valeur/10;
if (result!=0) {
Printf(result+0x30);
zero=0;
}
else if (zero==0) Printf('0');
result=valeur%10;
Printf(result+0x30);
}
// convert 16 bits binary value to HEX and send it on the UART
void Print_hex(unsigned int valeur)
{
const char hexa[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
Printf(hexa[(valeur>>12)&0x000F]);
Printf(hexa[(valeur>>8)&0x000F]);
Printf(hexa[(valeur>>4)&0x000F]);
Printf(hexa[valeur&0x000F]);
}
// convert 16 bits binary value to byte and send it on the UART
void Print_byte(unsigned int valeur)
{
unsigned int result;
result=valeur;
Printf(result);
}
Referencias
http://picmania.garcia-cuervo.net/picc.php#COMBUF232
http://picmania.garcia-cuervo.net/picc_servos_x_8.php
http://sdcc.sourceforge.net/doc/sdccman.pdf
http://pinguino.walii.es/archives/161
http://karoshi.auic.es/index.php?topic=1689.0
http://jpmandon.blogspot.com/
Mensaje maigke el Vie 17 Sep 2010 - 9:32
Buenas noches a todos (Aquí en Mx es de madrugada)
Bien en esta ocasion les presento un codigo que es original de RedPIc, y que gracias a la lógica que el presenta en su sitio, he aprendido bastante. Pues bien, aqui esta el código que el nos presenta para controlar 8 servomotores con una sola interrupcion del timer1 a 16 bits, pero con las siguientes modificaciones:
-- El pic es un 18F2550
-- El lenguaje claro que es SDCC y pues así lo hace libre esto.
-- El oscilador es a 20MHz, pero basado en el proyecto Pinguino se establece que el micro trabaje a 12MIPS.
-- Tome algunos ejemplos de como trabaja el proyecto Pinguino de Jean - Pierre Mandon.
-- Aun el micro no entiende lo que le mandes por el puerto paralelo serial (andaba medio dormido). cyclops pero ya mero
sin mas preambulos, les muestro el código, que digamoslo así, es casí una copia fiel, pero con sus bueno retoques, algo importante, no se la causa del por que el SDCC no trabaja bien con las operaciones de 16bits, así que tuve que hacer algunos ajustes, así que tuve que gastar aun mas recursos de los que ya de por si SDCC requiere. posterior les presento algunas pantallas.
Espero sus notas y comentarios:, por cierto este post, se puede ligar al de GAMBAS + pic16f628 + puerto serial. Wink
/* ----------------------------------------------------------------------- */
/* Plantilla generada por Piklab */
/*
La configuracion del micro nos permite trabajar un con XT de 20MHZ
y pero usar el PLL con el propósito de alcanzar los 12MIPS
*/
#include <pic18f2550.h>
#include <delay.h>
#include <uart18f2550.c>
/* ----------------------------------------------------------------------- */
/* Bits de configuración: adapte los parámetros a su necesidad */
code char at __CONFIG1L CONFIG1L = _PLLDIV_DIVIDE_BY_5__20MHZ_INPUT__1L & _CPUDIV__OSC1_OSC2_SRC___1__96MHZ_PLL_SRC___2__1L & _USBPLL_CLOCK_SRC_FROM_96MHZ_PLL_2_1L;
code char at __CONFIG1H CONFIG1H = _OSC_HS__HS_PLL__USB_HS_1H & _FCMEN_ON_1H & _IESO_ON_1H;
code char at __CONFIG2L CONFIG2L = _PUT_ON_2L & _BODEN_ON_2L & _BODENV_4_2V_2L & _VREGEN_ON_2L;
code char at __CONFIG2H CONFIG2H = _WDT_DISABLED_CONTROLLED_2H & _WDTPS_1_32768_2H;
code char at __CONFIG3H CONFIG3H = _CCP2MUX_RC1_3H & _PBADEN_PORTB_4_0__CONFIGURED_AS_DIGITAL_I_O_ON_RESET_3H & _LPT1OSC_ON_3H & _MCLRE_MCLR_OFF_RE3_ON_3H;
code char at __CONFIG4L CONFIG4L = _STVR_ON_4L & _LVP_OFF_4L & _ENHCPU_OFF_4L & _BACKBUG_OFF_4L;
code char at __CONFIG5L CONFIG5L = _CP_0_OFF_5L & _CP_1_OFF_5L & _CP_2_OFF_5L & _CP_3_OFF_5L;
code char at __CONFIG5H CONFIG5H = _CPB_OFF_5H;
code char at __CONFIG6L CONFIG6L = _WRT_0_OFF_6L & _WRT_1_OFF_6L & _WRT_2_OFF_6L & _WRT_3_OFF_6L;
code char at __CONFIG6H CONFIG6H = _WRTC_OFF_6H & _WRTB_OFF_6H;
code char at __CONFIG7L CONFIG7L = _EBTR_0_OFF_7L & _EBTR_1_OFF_7L & _EBTR_2_OFF_7L & _EBTR_3_OFF_7L;
code char at __CONFIG7H CONFIG7H = _EBTRB_OFF_7H;
//Definiciones de servos
#define SERVO1 LATBbits.LATB0
#define SERVO2 LATBbits.LATB1
#define SERVO3 LATBbits.LATB2
#define SERVO4 LATBbits.LATB3
#define SERVO5 LATBbits.LATB4
#define SERVO6 LATBbits.LATB5
#define SERVO7 LATBbits.LATB6
#define SERVO8 LATBbits.LATB7
#define CSERVO1 TRISBbits.TRISB0
#define CSERVO2 TRISBbits.TRISB1
#define CSERVO3 TRISBbits.TRISB2
#define CSERVO4 TRISBbits.TRISB3
#define CSERVO5 TRISBbits.TRISB4
#define CSERVO6 TRISBbits.TRISB5
#define CSERVO7 TRISBbits.TRISB6
#define CSERVO8 TRISBbits.TRISB7
typedef enum{false = 0, true = 1} boolean;
//Constantes para la definición de ventanas
const unsigned Ticks4WindowH = 0x75;
const unsigned Ticks4WindowL = 0x2F;
const unsigned Ticks4CenterH = 0x46;
const unsigned Ticks4CenterL = 0x4F;
const unsigned Ticks4MinimumH = 0x17;
const unsigned Ticks4MinimumL = 0x6F;
const unsigned Ticks4MaximumH = 0x6B;
const unsigned Ticks4MaximumL = 0xCF;
static unsigned int Ticks4NextInterruptH = 0xCF;
static unsigned int Ticks4NextInterruptL = 0x2C;
static unsigned short Servo_PWMH[8];
static unsigned short Servo_PWML[8];
static unsigned short Servo_Idx = 0;
#define SERVO1_ON true
#define SERVO2_ON false
#define SERVO3_ON false
#define SERVO4_ON false
#define SERVO5_ON false
#define SERVO6_ON false
#define SERVO7_ON false
#define SERVO8_ON false
//definicion de teclas
#define INTRO 0x0D
#define RETROCESO 0x08
#define ESCAPE 0x1B
unsigned short flag_Phase;
unsigned short j=0xFF;
/*Seccion para la comunicacion en serial*/
#define lenbuff 10
unsigned char xbuff=0x00;
unsigned char cbuff[lenbuff];
char rcvchar=0x00;
unsigned char flagcommand = 0;
//Prototipos
void init_board(void);
void EnableTimer1Interrupt();
void Tmr1Carga(unsigned char high, unsigned char low);
void delay_ms(int milis);
void delay_us(int milis);
//Sección de interrupciones
static void isr_Tmr1() interrupt 1 //Esta es una interrupcion de alta prioridad
{
PIE1bits.RCIE=0; //deshabilitamos la interrupcion del puerto serie
if(flag_Phase == 1)
{
if(Servo_Idx == 0 && SERVO1_ON) {SERVO1 = 1;}
if(Servo_Idx == 1 && SERVO2_ON) {SERVO2 = 1;}
if(Servo_Idx == 2 && SERVO3_ON) {SERVO3 = 1;}
if(Servo_Idx == 3 && SERVO4_ON) {SERVO4 = 1;}
if(Servo_Idx == 4 && SERVO5_ON) {SERVO5 = 1;}
if(Servo_Idx == 5 && SERVO6_ON) {SERVO6 = 1;}
if(Servo_Idx == 6 && SERVO7_ON) {SERVO7 = 1;}
if(Servo_Idx == 7 && SERVO8_ON) {SERVO8 = 1;}
Ticks4NextInterruptH = 0xFF - Servo_PWMH[Servo_Idx];
Ticks4NextInterruptL = 0xFF - Servo_PWML[Servo_Idx];
Tmr1Carga(Ticks4NextInterruptH,Ticks4NextInterruptL);
}
if(flag_Phase == 0)
{
if(Servo_Idx == 0 && SERVO1_ON) {SERVO1 = 0;}
if(Servo_Idx == 1 && SERVO2_ON) {SERVO2 = 0;}
if(Servo_Idx == 2 && SERVO3_ON) {SERVO3 = 0;}
if(Servo_Idx == 3 && SERVO4_ON) {SERVO4 = 0;}
if(Servo_Idx == 4 && SERVO5_ON) {SERVO5 = 0;}
if(Servo_Idx == 5 && SERVO6_ON) {SERVO6 = 0;}
if(Servo_Idx == 6 && SERVO7_ON) {SERVO7 = 0;}
if(Servo_Idx == 7 && SERVO8_ON) {SERVO8 = 0;}
Ticks4NextInterruptH = 0xFF - Ticks4WindowH;
Ticks4NextInterruptL = 0xFF - Ticks4WindowL;
if(Ticks4NextInterruptL + Servo_PWML[Servo_Idx] > 0xFF)
{
Ticks4NextInterruptL = Ticks4NextInterruptL + Servo_PWML[Servo_Idx];
Ticks4NextInterruptH = Ticks4NextInterruptH + Servo_PWMH[Servo_Idx] + 1;
}
else
{
Ticks4NextInterruptL = Ticks4NextInterruptL + Servo_PWML[Servo_Idx];
Ticks4NextInterruptH = Ticks4NextInterruptH + Servo_PWMH[Servo_Idx];
}
Tmr1Carga(Ticks4NextInterruptH,Ticks4NextInterruptL);
if(++Servo_Idx > 7 ) Servo_Idx = 0;
}
if(++flag_Phase > 1) flag_Phase = 0;
//Esta instruccion se esta ejecutando cada 13ms con un xtal de 20MHz
LATBbits.LATB7^=1; //complementamos el valor del bit RB7
// RB7^=1; <- dice que no se puede así
PIR1bits.TMR1IF=0; //limpiamos la bandera de interrupcion
PIE1bits.RCIE=1; //habilitamos la interrupcion del puerto serie
//Carga el timer para 1ms
//Tmr1Carga(0xD1,0x1F); //TMR1 = FFFF - FF00
}
static void isr_Serial() interrupt 2 //Esta es una interrupcion de baja prioridad
{
PIR1bits.RCIF=0;
rcvchar=RCREG;
Printf(rcvchar);
}
//Funcion Principal
void main() {
//declaracion de variables
int i=0;
int button_down=1;
int valTimer=0;
RCONbits.IPEN=1; //interrupciones por prioridad habilitadas
init_board();
Print_str("Dispositivo inicializado");
Printf(INTRO);
Print_str("PIC18F2550 en SDCC");
Printf(INTRO);
for (i=0;i<9;i++)
{
Servo_PWMH[i] = Ticks4MaximumH;
Servo_PWML[i] = Ticks4MaximumL;
}
EnableTimer1Interrupt();
while (true)
{
}
}
void init_board(void) {
ADCON1=0x7; // PORTA used for digital I/O
TRISAbits.TRISA4=true; // configure PORTA4 for input (pushbutton)
/* Configuramos las salidas de los servomotores*/
CSERVO1 = false;
CSERVO2 = false;
CSERVO3 = false;
CSERVO4 = false;
CSERVO5 = false;
CSERVO6 = false;
CSERVO7 = false;
CSERVO8 = false;
//Configuramos la comunicacion serial --rutina de jean Pierre Mandon
setup_UART(B57600);
}
void EnableTimer1Interrupt()
{
TMR1H=0xFF;
TMR1L=0x00; //TMR1 = FFFF - FF00
T1CON=1; //Timer1 preescaler 1 interno, carga de 8 bits
PIE1bits.TMR1IE=1;
INTCONbits.PEIE=1;
INTCONbits.GIE=1;
}
void Tmr1Carga(unsigned char high, unsigned char low)
{
TMR1H=high;
TMR1L=low;
}
void delay_ms(int milis){
delay1ktcy(5*milis);
}
void delay_us(int milis){
delay10tcy(1*milis);
}
Y esta es la rutina de comunicacion serial de Jean Pierre que use
// UART Library for PIC 18F2550
// SDCC version / small device c compiler
// written by Jean-Pierre MANDON 2008 jp.mandon@free.fr
// www.pictec.org
/*
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
In other words, you are welcome to use, share and improve this program.
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding!
*/
// this program is intended for an oscillator frequency of 20 Mhz
// SPBRG value for FOSC 20 Mhz
#define B300 1,0,0x27,0x0F
#define B1200 1,0,0x09,0xC3
#define B2400 1,0,0x04,0xE1
#define B4800 1,0,0x02,0x70
#define B9600 0,0,0x00,0x4D
#define B19200 0,0,0x00,0x26
#define B57600 1,1,0x00,0xCF
#define B115200 1,1,0x00,0x67
// local definition UART.C
#define BUFFER 128 // rx buffer length
char rx[BUFFER]; // this is the buffer
unsigned char wpointer,rpointer; // write and read pointer
#define charreceived (wpointer!=rpointer)
#define SERIAL
typedef struct
{
unsigned int
hhigh4:4,
hlow4:4,
lhigh4:4,
llow4:4;
} bitfield;
// setup PIC UART
void setup_UART(unsigned char brg16,unsigned char brgh,unsigned char highbyte,unsigned char lowbyte)
{
TXSTAbits.BRGH=brgh&1; // set BRGH bit
BAUDCONbits.BRG16=brg16&1; // set 16 bits SPBRG
SPBRGH=highbyte; // set UART speed SPBRGH
SPBRG=lowbyte; // set UART speed SPBRGL
RCSTA=0x90; // set RCEN and SPEN
BAUDCONbits.RCIDL=1; // set receive active
PIE1bits.RCIE=1; // enable interrupt on RX
INTCONbits.PEIE=1; // enable peripheral interrupts
IPR1bits.RCIP=0; // define low priority for RX interrupt
wpointer=1; // initialize write pointer
rpointer=1; // initialize read pointer
TXSTAbits.TXEN=1; // enable TX
INTCONbits.GIE=1;
}
// UART write char
void Printf(unsigned char caractere)
{
while (!TXSTAbits.TRMT);
TXREG=caractere; // yes, send char
}
// rxint is called by interruption service routine
void rxint(void)
{
char caractere;
unsigned char newwp;
PIR1bits.RCIF=0; // clear RX interrupt flag
caractere=RCREG; // take received char
if (wpointer!=BUFFER-1) // if not last place in buffer
newwp=wpointer+1; // place=place+1
else
newwp=1; // else place=1
if (rpointer!=newwp) // if read pointer!=write pointer
rx[wpointer++]=caractere; // store received char
if (wpointer==BUFFER) // if write pointer=length buffer
wpointer=1; // write pointer = 1
}
// get char
unsigned char getch()
{
unsigned char caractere=0;
if (charreceived)
{
caractere=rx[rpointer++];
if (rpointer==BUFFER)
rpointer=1;
}
return(caractere);
}
// clear rx buffer
void clear_buffer(void) {
wpointer=1;
rpointer=1;
}
// write a string on the UART
void Print_str(const char* text)
{
unsigned char i=0;
while ( text[i] != 0 )
Printf( text[i++] );
}
// convert 16 bits binary value to DEC and send it on the UART
void Print_dec(unsigned int valeur)
{
unsigned char result;
unsigned char zero=1;
result=valeur/10000;
if (result!=0) {
Printf(result+0x30);
zero=0;
}
valeur=valeur%10000;
result=valeur/1000;
if (result!=0) {
Printf(result+0x30);
zero=0;
}
else if (zero==0) Printf('0');
valeur=valeur%1000;
result=valeur/100;
if (result!=0) {
Printf(result+0x30);
zero=0;
}
else if (zero==0) Printf('0');
valeur=valeur%100;
result=valeur/10;
if (result!=0) {
Printf(result+0x30);
zero=0;
}
else if (zero==0) Printf('0');
result=valeur%10;
Printf(result+0x30);
}
// convert 16 bits binary value to HEX and send it on the UART
void Print_hex(unsigned int valeur)
{
const char hexa[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
Printf(hexa[(valeur>>12)&0x000F]);
Printf(hexa[(valeur>>8)&0x000F]);
Printf(hexa[(valeur>>4)&0x000F]);
Printf(hexa[valeur&0x000F]);
}
// convert 16 bits binary value to byte and send it on the UART
void Print_byte(unsigned int valeur)
{
unsigned int result;
result=valeur;
Printf(result);
}
Referencias
http://picmania.garcia-cuervo.net/picc.php#COMBUF232
http://picmania.garcia-cuervo.net/picc_servos_x_8.php
http://sdcc.sourceforge.net/doc/sdccman.pdf
http://pinguino.walii.es/archives/161
http://karoshi.auic.es/index.php?topic=1689.0
http://jpmandon.blogspot.com/
Etiquetas:
electrónica,
linux,
sdcc,
Serial,
servo,
servomotor
Suscribirse a:
Entradas (Atom)













