Implementación de una capa de protocolo CAN en el software

Fondo

Estoy desarrollando un proyecto que requerirá las modestas especificaciones del microcontrolador de:

  • 8 ADC de 12 bits, 10 kHz
  • 1kB de RAM
  • 48-QFN o huella más pequeña
  • Protocolo de comunicación de corrección de errores y resistente al ruido conectable en cadena de 20 kbps

Los requisitos de procesamiento de señales son bastante bajos y la mayoría se puede exportar al procesador principal del sistema. Las primeras tres especificaciones son fáciles de cumplir y se pueden hacer por menos de $2 en cantidad. Sin embargo, la comunicación se llevará a cabo en un entorno con mucho ruido eléctrico, por lo que las redes vulnerables al ruido como LIN e I2C están descartadas. Un argumento adicional en contra de LIN es que me gustaría ejecutar todo a 5 V o 3,3 V, y los transceptores LIN requieren 12 V, por lo que requerirían un regulador o cable adicional por placa de sensor. Inicialmente elegí CAN para esta tarea. Sin embargo, los controladores CAN agregan un costo considerable y tengo curiosidad por saber si esto se puede hacer en el software.

Capa física CAN

La especificación CAN define las capas física y de enlace de datos del modelo de referencia de la red OSI. Existen muchos IC económicos de 8 pines, como NXP TJA1040/50 , Maxim MAX3058/59 , Microchip MCP2551 y TI SN65HVD1050 para implementar la capa física. La implementación de la capa física con convertidores D/A o amplificadores operacionales sería difícil, si no imposible, por lo que estos circuitos integrados bien valen el dólar que cuestan.

Enlace de datos CAN/capa de protocolo

Para la capa de enlace de datos, algunos microcontroladores agregan módulos de protocolo CAN a las capas de comunicaciones básicas UART, I2C y SPI. Sin embargo, estos son significativamente más caros que los chips básicos.

Investigación del costo de los módulos de protocolo CAN

Para corroborar esta afirmación, aquí hay algunos micros populares en versiones CAN y no CAN, de:

  • ATmega16 - ATMEGA16M1 (con CAN): $3.87, ATMEGA168A (sin CAN): $3.23
  • dsPIC - DSPIC33FJ64MC802 (con CAN): $6.14, DSPIC33FJ64GP202 (sin CAN): $5.48
  • PIC18 - PIC18F2480 (con CAN): $6.80, PIC18F24J10 (sin CAN): $2.10
  • Cortex-M3 - STM32F103C4T6A (con CAN): $6.50, STM32F100C4T6B (sin CAN): $2.73

Para ser justos, solo comparé microcontroladores con tamaños de memoria equivalentes, sin embargo, muchas de las versiones que no son CAN están disponibles con tamaños de memoria más pequeños por menos. Los controladores CAN externos, como el Microchip MCP2515 , cuestan casi $ 2, por lo que obviamente es más rentable tener el CAN integrado en el microcontrolador si tiene la opción.

Curiosamente, la parte ATmega es, con mucho, la parte equipada con CAN más barata en el inventario de Digikey.

Función de la capa de protocolo CAN

El módulo CAN que se encuentra en los microcontroladores dsPIC hace lo siguiente:

El módulo de bus CAN consta de un motor de protocolo y almacenamiento/control de mensajes. El motor de protocolo CAN maneja todas las funciones para recibir y transmitir mensajes en el bus CAN. Los mensajes se transmiten cargando primero los registros de datos apropiados. El estado y los errores se pueden comprobar leyendo los registros apropiados. Cualquier mensaje detectado en el bus CAN se verifica en busca de errores y luego se compara con los filtros para ver si debe recibirse y almacenarse en uno de los registros de recepción.

Esto parece bastante factible en el software.

La pregunta

¿Se puede usar una capa de protocolo de software para implementar la especificación CAN con solo un microcontrolador económico equipado con UART y un transceptor CAN? Si es así, ¿existen implementaciones de código abierto?

Alternativamente, ¿se pueden usar transceptores CAN con UART para implementar un protocolo personalizado? Estoy bien con una topología de maestro único; Entiendo que el arbitraje puede ser difícil de lograr en un protocolo personalizado.

CAN también es de 12v, ya que fue desarrollado para uso automotriz.
@Kenny: los niveles de voltaje utilizados en los transceptores anteriores son 5V.
Si va a considerar la serie STM32F, ¿puedo sugerir también esta parte NXP? Es un núcleo Cortex-M0. search.digikey.com/scripts/DkSearch/…
@Jon: esos no estaban necesariamente bajo consideración, y un M0 sería ideal para este caso de uso. Sin embargo, considere que las partes del Nuvoton M052LAN también son Cortex-M0, y aproximadamente la mitad del precio en cantidad ($ 1.21 vs. $ 2.35), pero no tiene el modulo CAN. Ese tipo de diferencia de precio es mi motivación.
es posible que también desee considerar la clasificación operativa. La mayoría de las piezas compatibles con CAN serán industriales o automotrices frente a comerciales para variantes que no sean CAN.
Fantásticos recursos: documentos de microchip an713, an754 y an228. Aquí hay un 713: ww1.microchip.com/downloads/cn/AppNotes/cn_00713a.pdf

Respuestas (4)

Creo que implementar el protocolo CAN en el firmware solo será difícil y llevará un tiempo hacerlo bien. No es una buena idea.

Sin embargo, sus precios son altos. Acabo de comprobar, y un dsPIC 33FJ64GP802 en paquete QFN se vende por 3,68 USD en microchipdirect por 1000 piezas. El precio será menor para los volúmenes reales de producción.

El periférico de hardware CAN hace algunas cosas reales por usted, y el incremento de precio no se acerca a lo que está reclamando.

Agregado:

Dado que parece estar decidido a probar la ruta del firmware, estos son algunos de los problemas obvios que le vienen a la mente. Lo más probable es que haya otros problemas que aún no se me han ocurrido.

Quiere hacer CAN a 20 kbit/s. Esa es una tasa muy lenta para CAN, que sube a 1 Mbit/s durante al menos decenas de metros. Para darle un punto de datos, el estándar de señalización de a bordo NMEA 2000 se superpone en CAN a 200 kbits/s, y eso está destinado a ir de un extremo al otro de un barco grande.

Puede pensar que todo lo que necesita es una interrupción por bit y puede hacer todo lo que necesita en esa interrupción. Eso no funcionará porque hay varias cosas sucediendo en cada tiempo de bit CAN. Hay que hacer dos cosas en particular a nivel de subbits. El primero detecta una colisión y el segundo ajusta la tasa de bits sobre la marcha.

Hay dos estados de señalización en un bus CAN, recesivo y dominante. Recesivo es lo que sucede cuando nada conduce el autobús. Ambas líneas están unidas por un total de 60 Ω. Un bus CAN normal implementado por chips comunes como el MCP2551, debe tener terminadores de 120 Ω en ambos extremos, por lo tanto, un total de 60 Ω uniendo pasivamente las dos líneas diferenciales. El estado dominante es cuando ambas líneas se separan activamente, en algún lugar alrededor de 900mV desde el estado recesivo si mal no recuerdo. Básicamente, esto es como un bus de colector abierto, excepto que se implementa con un par diferencial. La barra está en estado recesivo si CANH-CANL < 900mV y dominante cuando CANH-CANL > 900mV. El estado dominante señala 0 y el recesivo 1.

Cada vez que un nodo "escribe" un 1 en el bus (lo suelta), verifica si algún otro nodo está escribiendo un 0. Cuando encuentra el bus en estado dominante (0) cuando cree que está enviando y el el bit actual que está enviando es un 1, entonces eso significa que alguien más también está enviando. Las colisiones solo importan cuando los dos remitentes no están de acuerdo, y la regla es que el que envía el estado recesivo retrocede y aborta su mensaje. El nodo que envía el estado dominante ni siquiera sabe que esto sucedió. Así es como funciona el arbitraje en un bus CAN.

Las reglas de arbitraje del bus CAN significan que debe estar observando el bus a la mitad de cada bit que está enviando como 1 para asegurarse de que alguien más no esté enviando un 0. Esta verificación generalmente se realiza aproximadamente 2/3 del camino en el bit , y es la limitación fundamental en la longitud del bus CAN. Cuanto más lenta sea la tasa de bits, más tiempo habrá para la propagación del peor de los casos de un extremo al otro del bus y, por lo tanto, más largo puede ser el bus. Esta verificación debe realizarse cada bit donde crea que es el propietario del bus y esté enviando un bit 1.

Otro problema es el ajuste de la tasa de bits. Todos los nodos de un bus deben estar de acuerdo con la tasa de bits, más estrechamente que con RS-232. Para evitar que las pequeñas diferencias de reloj se acumulen en errores significativos, cada nodo debe poder hacer un bit un poco más largo o más corto que su valor nominal. En el hardware, esto se implementa ejecutando un reloj entre 9 y 20 veces más rápido que la tasa de bits. Los ciclos de este reloj rápido se denominan cuantos de tiempo. Hay formas de detectar que el comienzo de nuevos bits se está desviando con respecto a donde cree que deberían estar. Las implementaciones de hardware luego agregan u omiten los cuantos de una vez en un bit para volver a sincronizar. Hay otras formas de implementar esto, siempre que pueda ajustarse a pequeñas diferencias de fase entre los tiempos de bit esperados y los tiempos de bit medidos reales.

De cualquier manera, estos mecanismos requieren que se hagan varias cosas en varios momentos dentro de un bit. Este tipo de temporización será muy complicado en el firmware o requerirá que el bus funcione muy lentamente. Supongamos que implementa un sistema de cuantos de tiempo en el firmware a 20 kbits/s. Con un mínimo de 9 cuantos de tiempo por bit, eso requeriría una interrupción de 180 kHz. Eso es ciertamente posible con algo como un dsPIC 33F, pero consumirá una fracción significativa del procesador. A la velocidad de instrucción máxima de 40 MHz, obtiene 222 ciclos de instrucción por interrupción. No debería llevar tanto tiempo realizar todas las comprobaciones, pero probablemente entre 50 y 100 ciclos, lo que significa que el 25-50 % del procesador se usará para CAN y tendrá que adelantarse a todo lo demás que se esté ejecutando. Eso evita que muchas aplicaciones que estos procesadores ejecutan a menudo, como el control pulso por pulso de una fuente de alimentación conmutada o un controlador de motor. La latencia de 50-100 ciclos en cualquier otra interrupción sería un obstáculo total para muchas de las cosas que he hecho con chips como este.

Entonces vas a gastar el dinero para hacer CAN de alguna manera. Si no es en el periférico de hardware dedicado diseñado para ese propósito, entonces en obtener un procesador más grande para manejar la sobrecarga significativa de firmware y luego lidiar con la latencia de interrupción impredecible y posible grande para todo lo demás.

Luego está la ingeniería inicial. El periférico CAN simplemente funciona. Según su comentario, parece que el costo incremental de este periférico es de $0,56. Eso me parece una ganga. A menos que tenga un producto de gran volumen, no hay forma de que recupere el tiempo y los gastos considerables que llevará implementar CAN solo en el firmware. Si sus volúmenes son tan altos, los precios que hemos estado mencionando no son realistas de todos modos, y el diferencial para agregar el hardware CAN será menor.

Realmente no veo que esto tenga sentido.

Valoro su opinión, pero tengo curiosidad por saber por qué nadie ha tratado de solucionar las dificultades. ¡Todos los proyectos tendrán esos problemas! Te dejaré saber cómo resulta si termino intentándolo.
En cantidades de 1000, encuentro un precio de $3.12 para el dsPIC33FJ64GP202 de microchipdirect - ¡Una diferencia de valor total de $560! Al menos vale la pena intentarlo. Estaba citando precios por cada uno simplemente porque era más fácil obtener números para piezas individuales sin tener que preocuparme por el bobinado, la cantidad estándar del paquete, etc.
@Kevin, los precios de cantidades bajas no siempre son proporcionales a los precios de cantidades altas. No sé cuántas de estas cosas planea hacer, pero $560 no comenzarán a pagar la ingeniería para hacer CAN en el firmware. Agregaré a mi respuesta explicando algunas de las dificultades que encontrará.
Jugué un poco con esto y descubrí que un signo de dólar al principio del mensaje estropeaba el formato de todo lo que pasaba. Aparentemente, hay un error desagradable en algún lugar del software de formateo. Reemplacé el signo de dólar con "USD" y ahora el formato es el previsto.
El error de formateo es curioso, pero quería decir que estaba decidido a explorar la ruta del firmware, no necesariamente a intentarlo. Agradezco su voz de experiencia diciéndome "No", pero quería asegurarme de que no fuera descartado de plano. Ciertamente ha proporcionado suficientes razones para descartarlo sin demasiada experimentación adicional.
@Olin, solo un poco, pero NMEA está a 250 Kbs ( en.wikipedia.org/wiki/NMEA_2000 ). Y para otros se basa en el estándar automotriz en.wikipedia.org/wiki/J1939
La respuesta es sí, pero estoy totalmente de acuerdo con Olin aquí. De hecho, trabajo a tiempo completo en este campo. Yo uso el chip dsPIC33FJ256. El tiempo dedicado a hacer que las cosas se escriban con el enfoque bit-bang simplemente elimina la ventaja de costo de tener hardware que lo haga por usted y usted reinvente la rueda. Sin mencionar que cualquier otra cosa que esté haciendo en el hardware deberá planificarse cuidadosamente por encima de todo. Además, me pregunto si está buscando otros protocolos de nivel superior, como ISO14229 o OSEK/Autosar NetworkManagement.
El problema de formato es probablemente LaTeX. meta.electronics.stackexchange.com/questions/434/…
@KevinVermeer Estoy investigando exactamente esto ahora mismo. Ignorando la información de Olin sobre pisotear el autobús, interpretar la capa física no es trivial. Una vez que los fabricantes de IC manejan eso, es bastante fácil proporcionar los otros chips de bonificación como la oferta mcp2551.

Usamos el PIC18F25K80 . Si bien no tiene un DSP, cuesta ~ $ 2 en cantidad. Es casi un sustituto directo del PIC18F2480 que mencionas. Usamos el compilador CCS y su pila de software para CAN, que probablemente se transfirió desde Microchip. Funciona bien para todo lo que he necesitado y probado.

No busqué ECAN. Nombre tonto de Microchip, ¡pero tendré que leer más detenidamente la próxima vez! Como dije, mis necesidades de procesamiento de señal son bajas, por lo que no creo que necesite un DSP real.

Si estoy leyendo esto correctamente, parece que desea utilizar la funcionalidad CAN bit-bash utilizando solo un UART y algún firmware inteligente. Confía en mí, esto nunca funcionará. Sugiero leer un buen texto sobre las complejidades de CAN o CANopen. Habrá erradicado cualquier ahorro de costos que esté buscando siguiendo esta ruta.

Usaría un microcontrolador con un módulo CAN y pasaría los $ 2 adicionales, o ¿ha pensado en un protocolo diferente que sea compatible con un UART, como Modbus sobre RS-485 ?

Estás leyendo bien. He leído detenidamente el folleto de formación de Vector sobre CAN. Parece que cada mensaje necesitará un preprocesamiento para CRC, pero el resto del paquete debería ser el mismo y solo tendré que seguir revisando la línea de recepción para ver si hay algún conflicto. Realmente no parece tan difícil como la gente lo hace parecer, pero definitivamente tomaré en cuenta tu consejo.
Sin embargo, me gusta la idea de Modbus sobre RS485. Parece que la mayoría de esos transceptores también tienen suministro de 5V; Tenía la impresión de que requería un voltaje de entrada +/- como RS232. Habrá que investigar eso.
¡Los golpes de bits ciertamente funcionarán! No es trivial como menciona Olin, arriba, pero se puede hacer. Personalmente lo he logrado tanto en una serie PIC18F como en una serie micro dsPIC33. Puedo subir la fuente PIC18F si realmente quieres verla. Sin embargo, no puedo dar la fuente dsPIC ya que es parte de un proyecto comercial en el que trabajo. En ambos casos usamos MCP2551 y también tengo código LIN. LIN es un poco más simple en la capa de protocolo, pero implementar horarios de LIN es un poco más difícil...
@EricM: ¿cuál fue la tasa de bits y pudo implementar la especificación CAN completa en el software? Me encantaría ver el código PIC18F para esto.
Sí, implementé la especificación CAN completa en la medida en que no dupliqué el módulo ECAN en el dsPIC que se ocupa de muchos aspectos. En la implementación de PIC18, golpeé el bus con la especificación completa y más tarde, y este código funcionará en un dsPIC haciendo uso de líneas GPIO. Actualizaré en unos días con un enlace al código.
El chip puede mantenerse al día con 1Mb. Hice muchas cosas feas para cumplir con las reglas de arbitraje... y sobre todo para aprender sobre CAN, pero no recomendaría esto en nada comercial. ¡Ve con el hardware! MCP2551 y MCP2515 son excelentes chips...

También estoy pensando en modificar el protocolo CAN en un PIC µC, así que, por favor, EricM, si realmente lo hiciste, responde e indica al menos qué tasa de bits y qué frecuencia central de PIC18F o DSPic obtuviste. ¡Gracias!

En general: RS 485 sería la solución para el problema principal planteado, pero también sería posible usar transceptores CAN (o incluso FlexRay) con comunicaciones UART no full-duplex (punto 2 punto) como todos esos protocolos utilice la codificación NRZ.

Pero en UART/V24/RS232, el dúplex completo se usa principalmente sin pensar en los detalles, por lo que tal vez necesite poner algo de cerebro en el superbucle o la máquina de estado de su aplicación...

Pero volvamos al bitbanging de CAN: he trabajado con CAN durante muchos años y nunca vi una implementación de bitbanging, pero por lo que puedo pensar, eso debería funcionar para tiempos de bit de hasta 100kBit con µC modernos como DSPic o ARM, etc. (con núcleos a 80 MHz o más...)

Al menos si solo se considera la relectura... El envío significaría algunos gastos generales en la preparación de las estructuras de bits para que no se pueda alcanzar el 100% de la carga del bus, pero en CAN más del 65% es raro en absoluto...

Bienvenido a StackExchange de ingeniería eléctrica. La primera parte de su respuesta no es realmente una respuesta en absoluto, por lo que hace una nueva pregunta si eso es lo que quiere. El OP preguntó específicamente sobre la implementación del software del protocolo CAN y su respuesta parece deambular sin abordar esa pregunta; por favor trate de permanecer en el tema de la pregunta.