class CAN – barramento de comunicação da rede de área de controlador¶
CAN implementa suporte tanto para CAN clássico (bxCAN, utilizado no OpenMV Cam M4 e M7) como para CAN FD (FDCAN, utilizado no OpenMV Cam H7, H7 Plus e Pure Thermal). Ao nível físico, o barramento CAN é composto por duas linhas, RX e TX. Para ligar uma OpenMV Cam a um barramento CAN é necessário utilizar um transcetor CAN para converter os sinais lógicos CAN do MCU para os níveis de tensão corretos no barramento.
CAN clássico em modo de loopback (sem transcetor):
from pyb import CAN
can = CAN(1, CAN.LOOPBACK)
# Accept messages with id 123, 124, 125 or 126.
can.setfilter(0, CAN.LIST16, 0, (123, 124, 125, 126))
can.send("message!", 123) # send a message with id 123
can.recv(0) # receive a message on FIFO 0
CAN FD com todas as funcionalidades opcionais ativadas (trama FD, comutação de taxa de bits, IDs de trama expandidos; fase de arbitragem de 500 kbit/s, fase de dados de 1 Mbit/s):
from pyb import CAN
can = CAN(
1,
CAN.NORMAL,
baudrate=500_000,
brs_baudrate=1_000_000,
sample_point=80,
)
# Accept any id in the range 0xFFF0 .. 0xFFFF.
can.setfilter(0, CAN.RANGE, 0, (0xFFF0, 0xFFFF))
can.send(b"a" * 64, 0xFFFF, fdf=True, brs=True, extframe=True)
can.recv(0)
As seguintes funções do módulo CAN e respetivos argumentos estão disponíveis tanto para controladores CAN clássico como FD, salvo indicação em contrário.
Construtores¶
- class pyb.CAN(bus: int | str, *args, **kwargs)¶
Constrói um objeto CAN no
busindicado (um índice periférico inteiro, por exemplo1paraCAN1,2paraCAN2). Sem parâmetros adicionais, o objeto é criado mas não inicializado (retém as definições anteriores do barramento, se existirem); se forem fornecidos argumentos adicionais, o barramento é inicializado. ConsulteCAN.init()para os parâmetros disponíveis.CAN(2)está ligado aos mesmos pinos de cabeçalho em todas as OpenMV Cam que expõempyb.CAN(M4 / M7 / H7 / H7 Plus / Pure Thermal):Sinal
Pino de cabeçalho
Notas
RXP3TXP2O periférico CAN fornece apenas sinais de nível lógico; é necessário um transcetor CAN externo para conduzir um barramento CAN real.
pyb.CANnão está disponível na OpenMV Cam N6.Métodos¶
- init(mode: int, prescaler: int = 100, *, sjw: int = 1, bs1: int = 6, bs2: int = 8, auto_restart: bool = False, baudrate: int = 0, sample_point: int = 75, num_filter_banks: int = 14, brs_sjw: int = 1, brs_bs1: int = 8, brs_bs2: int = 3, brs_baudrate: int = 0, brs_sample_point: int = 75) None¶
Inicializa o barramento CAN com os parâmetros indicados:
mode é um dos seguintes: NORMAL, LOOPBACK, SILENT, SILENT_LOOPBACK
prescaler é o valor pelo qual o relógio de entrada CAN é dividido para gerar o quantum de tempo de bit nominal. O prescaler pode ser um valor entre 1 e 1024, inclusive, para CAN clássico, e entre 1 e 512, inclusive, para CAN FD.
sjw é a largura de salto de ressincronização em unidades de quantum de tempo para bits nominais; pode ser um valor entre 1 e 4, inclusive, para CAN clássico, e entre 1 e 128, inclusive, para CAN FD.
bs1 define a posição do ponto de amostragem em unidades do quantum de tempo para bits nominais; pode ser um valor entre 1 e 16, inclusive, para CAN clássico, e entre 2 e 256, inclusive, para CAN FD.
bs2 define a posição do ponto de transmissão em unidades do quantum de tempo para bits nominais; pode ser um valor entre 1 e 8, inclusive, para CAN clássico, e entre 2 e 128, inclusive, para CAN FD.
auto_restart define se o controlador irá tentar automaticamente reiniciar as comunicações após entrar no estado bus-off; se esta opção estiver desativada,
restart()pode ser utilizado para sair do estado bus-offbaudrate se for fornecida uma taxa de baud diferente de 0, esta função tentará calcular automaticamente o tempo de bit nominal CAN (substituindo prescaler, bs1 e bs2) que satisfaz tanto a baudrate (dentro de .1%) como o sample_point desejado (para o 1% mais próximo). Para um controlo mais preciso do temporizador CAN, defina os parâmetros prescaler, bs1 e bs2 diretamente.
sample_point especifica a posição da amostra de bit em relação ao tempo de bit nominal total, expressa como uma percentagem inteira do tempo de bit nominal. O sample_point predefinido é 75%. Este parâmetro é ignorado a menos que baudrate esteja definido.
num_filter_banks para CAN clássico, este é o número de bancos que serão atribuídos ao CAN(1), os restantes 28 são atribuídos ao CAN(2).
Os parâmetros restantes estão presentes apenas em placas com suporte CAN FD e configuram a funcionalidade opcional CAN FD Bit Rate Switch (BRS):
brs_prescaler é o valor pelo qual o relógio de entrada CAN FD é dividido para gerar o quantum de tempo de bit de dados. O prescaler pode ser um valor entre 1 e 32, inclusive.
brs_sjw é a largura de salto de ressincronização em unidades de quantum de tempo para bits de dados; pode ser um valor entre 1 e 16, inclusive
brs_bs1 define a posição do ponto de amostragem em unidades do quantum de tempo para bits de dados; pode ser um valor entre 1 e 32, inclusive
brs_bs2 define a posição do ponto de transmissão em unidades do quantum de tempo para bits de dados; pode ser um valor entre 1 e 16, inclusive
brs_baudrate se for fornecida uma taxa de baud diferente de 0, esta função tentará calcular automaticamente o tempo de bit de dados CAN (substituindo brs_prescaler, brs_bs1 e brs_bs2) que satisfaz tanto a brs_baudrate (dentro de .1%) como o brs_sample_point desejado (para o 1% mais próximo). Para um controlo mais preciso do temporizador BRS, defina os parâmetros brs_prescaler, brs_bs1 e brs_bs2 diretamente.
brs_sample_point especifica a posição da amostra de bit em relação ao tempo de bit nominal total, expressa como uma percentagem inteira do tempo de bit nominal. O brs_sample_point predefinido é 75%. Este parâmetro é ignorado a menos que brs_baudrate esteja definido.
O quantum de tempo tq é a unidade de tempo básica para o barramento CAN. O tq é o valor do prescaler CAN dividido pelo PCLK1 (a frequência do barramento periférico interno 1); consulte
pyb.freq()para determinar o PCLK1.Um único bit é composto pelo segmento de sincronização, que tem sempre 1 tq. Segue-se o segmento de bit 1 e depois o segmento de bit 2. O ponto de amostragem é após o segmento de bit 1 terminar. O ponto de transmissão é após o segmento de bit 2 terminar. A taxa de baud será 1/bittime, onde bittime é 1 + BS1 + BS2 multiplicado pelo quantum de tempo tq.
Por exemplo, na OpenMV Cam H7 (PCLK1 = 100 MHz), CAN a 250 kbps com um ponto de amostragem de 75% pode ser configurado como
prescaler=25, sjw=1, bs1=11, bs2=4:tq = 25 / 100 MHz = 250 ns,bittime = (1 + 11 + 4) × 250 ns = 4 µs, ponto de amostragem =(1 + 11) / 16 = 75%, e a taxa de baud é1 / 4 µs = 250 kHz.Consulte a secção bxCAN / FDCAN do manual de referência STM32 para o MCU da OpenMV Cam para mais detalhes.
- restart() None¶
Força um reinício por software do controlador CAN sem repor a sua configuração.
Se o controlador entrar no estado bus-off, deixará de participar na atividade do barramento. Se o controlador não estiver configurado para reiniciar automaticamente (consulte
init()), então este método pode ser utilizado para desencadear um reinício, e o controlador seguirá o protocolo CAN para sair do estado bus-off e entrar no estado de erro ativo.
- state() int¶
Devolve o estado do controlador. O valor de retorno pode ser um dos seguintes:
CAN.STOPPED– o controlador está completamente desligado e reposto;CAN.ERROR_ACTIVE– o controlador está ligado e no estado de Erro Ativo (tanto TEC como REC são inferiores a 96);CAN.ERROR_WARNING– o controlador está ligado e no estado de Aviso de Erro (pelo menos um de TEC ou REC é 96 ou superior);CAN.ERROR_PASSIVE– o controlador está ligado e no estado de Erro Passivo (pelo menos um de TEC ou REC é 128 ou superior);CAN.BUS_OFF– o controlador está ligado mas não participa na atividade do barramento (TEC ultrapassou 255).
- info(list: list | None = None) list¶
Obtém informações sobre os estados de erro do controlador e os buffers TX e RX. Se list for fornecida, deverá ser um objeto lista com pelo menos 8 entradas, que serão preenchidas com as informações. Caso contrário, será criada e preenchida uma nova lista. Em ambos os casos, o valor de retorno do método é a lista preenchida.
Os valores na lista são:
Valor TEC
Valor REC
número de vezes que o controlador entrou no estado de Aviso de Erro (reiniciado para 0 após 65535)
número de vezes que o controlador entrou no estado de Erro Passivo (reiniciado para 0 após 65535)
número de vezes que o controlador entrou no estado Bus Off (reiniciado para 0 após 65535)
número de mensagens TX pendentes
número de mensagens RX pendentes no fifo 0
número de mensagens RX pendentes no fifo 1
- setfilter(bank: int, mode: int, fifo: int, params: Tuple[int, ...], *, rtr: Tuple[bool, ...] | None = None, extframe: bool = False) None¶
Configura um banco de filtros:
bank é o banco de filtros do controlador CAN clássico, ou o índice de filtro CAN FD, a configurar.
mode é o modo de funcionamento do filtro, consulte as tabelas abaixo.
fifo indica em qual fifo (0 ou 1) uma mensagem deve ser armazenada, se for aceite por este filtro.
params é uma matriz de valores que define o filtro. O conteúdo da matriz depende do argumento mode.
Conteúdo da matriz params para controladores CAN clássico (OpenMV Cam M4 / M7):
mode
Conteúdo de params
CAN.LIST16Quatro IDs de 16 bits que serão aceites.
CAN.LIST32Dois IDs de 32 bits que serão aceites.
CAN.MASK16Dois pares id/máscara de 16 bits, por exemplo
(1, 3, 4, 4). O primeiro par (1, 3) aceita todos os IDs com bit 0 = 1 e bit 1 = 0; o segundo par (4, 4) aceita todos os IDs com bit 2 = 1.CAN.MASK32Um par id/máscara de 32 bits (de resto igual a
CAN.MASK16).Conteúdo da matriz params para controladores CAN FD (OpenMV Cam H7 / H7 Plus / Pure Thermal):
mode
Conteúdo de params
CAN.RANGEDois IDs que formam um intervalo de IDs aceites.
CAN.DUALDois IDs que serão aceites (por exemplo
(1, 2)).CAN.MASKUm par
(id, mask)(por exemplo(0x111, 0x7FF)).rtr Para controladores CAN clássico, este é um array de booleanos que indica se um filtro deve aceitar uma mensagem de pedido de transmissão remota. Se este argumento não for fornecido, assume
Falsepara todas as entradas. O comprimento depende do mode:mode
len(rtr)Notas
CAN.LIST164
CAN.LIST322
CAN.MASK162
CAN.MASK321
Para CAN FD este argumento é ignorado.
extframe Se True, a trama terá um identificador expandido (29 bits), caso contrário é utilizado um identificador padrão (11 bits).
- clearfilter(bank: int, extframe: bool = False) None¶
Limpa e desativa um banco de filtros:
bank é o banco de filtros do controlador CAN clássico, ou o índice de filtro CAN FD, a limpar.
extframe Para controladores CAN FD, se True, limpa um filtro expandido (configurado com extframe=True), caso contrário limpa um identificador padrão (configurado com extframe=False).
- recv(fifo: int, list: list | None = None, *, timeout: int = 5000) list¶
Recebe dados no barramento:
fifo é um inteiro que indica o FIFO onde receber
list é um objeto lista opcional a ser utilizado como valor de retorno
timeout é o tempo limite em milissegundos para aguardar pela receção.
Valor de retorno: Uma lista com cinco valores.
O id da mensagem.
Um booleano que indica se o ID da mensagem é padrão ou expandido.
Um booleano que indica se a mensagem é uma mensagem RTR.
O valor FMI (Filter Match Index).
Um array com os dados.
Se list for
None, será alocada uma nova lista, bem como um novo objeto bytes para conter os dados (como quinto elemento da lista).Se list não for
None, deverá ser um objeto lista com pelo menos cinco elementos. O quinto elemento deverá ser um objeto memoryview criado a partir de um bytearray ou de um array do tipo “B” ou “b”, e este array deverá ter espaço suficiente para pelo menos 8 bytes. O objeto lista será então preenchido com os primeiros quatro valores de retorno acima, e o objeto memoryview será redimensionado in-place para o tamanho dos dados e preenchido com esses dados. Os mesmos objetos lista e memoryview podem ser reutilizados em chamadas subsequentes a este método, proporcionando uma forma de receber dados sem utilizar a heap. Por exemplo:buf = bytearray(8) lst = [0, 0, 0, 0, memoryview(buf)] # No heap memory is allocated in the following call can.recv(0, lst)
- send(data: int | bytes | bytearray, id: int, *, timeout: int = 0, rtr: bool = False, extframe: bool = False, fdf: bool = False, brs: bool = False) None¶
Envia uma mensagem no barramento:
data são os dados a enviar (um inteiro a enviar, ou um objeto buffer).
id é o id da mensagem a enviar.
timeout é o tempo limite em milissegundos para aguardar pelo envio.
rtr é um booleano que especifica se a mensagem deve ser enviada como um pedido de transmissão remota. Se rtr for True, apenas o comprimento de data é utilizado para preencher o campo DLC da trama; os bytes reais em data não são utilizados.
extframe se True, a trama terá um identificador expandido (29 bits), caso contrário é utilizado um identificador padrão (11 bits).
fdf para controladores CAN FD, se definido como True, a trama terá formato de trama FD, que suporta payloads de dados até 64 bytes.
brs para controladores CAN FD, se definido como True, o modo de comutação de taxa de bits é ativado, no qual a fase de dados é transmitida a uma taxa de bits diferente. Consulte
CAN.init()para os parâmetros de configuração do temporizador de bit de dados.
Se o timeout for 0, a mensagem é colocada num buffer em um dos três buffers de hardware e o método retorna imediatamente. Se os três buffers estiverem em uso, é lançada uma exceção. Se o timeout não for 0, o método aguarda até que a mensagem seja transmitida. Se a mensagem não puder ser transmitida dentro do tempo especificado, é lançada uma exceção.
Valor de retorno:
None.
- rxcallback(fifo: int, fun: Callable[[CAN, int], None] | None) None¶
Regista uma função a ser chamada quando uma mensagem é aceite num FIFO vazio:
fifo é o FIFO de receção.
fun é a função a ser chamada quando o FIFO fica não vazio.
A função de callback recebe dois argumentos: o primeiro é o próprio objeto CAN; o segundo é um inteiro que indica o motivo do callback:
Motivo
Significado
0Uma mensagem foi aceite num FIFO vazio.
1O FIFO está cheio.
2Uma mensagem foi perdida devido a um FIFO cheio.
Exemplo de utilização de rxcallback:
def cb0(bus, reason): print('cb0') if reason == 0: print('pending') if reason == 1: print('full') if reason == 2: print('overflow') can = CAN(1, CAN.LOOPBACK) can.rxcallback(0, cb0)
Constantes¶
Constantes de modo de barramento (argumento
modedeinit()):- NORMAL: int¶
O controlador participa normalmente no barramento – transmite as suas próprias tramas e confirma as tramas recebidas válidas.
- LOOPBACK: int¶
Modo de loopback interno: o controlador é desconectado dos pinos e encaminha as tramas transmitidas diretamente de volta para o caminho de receção. Útil para autotestes sem transcetor.
- SILENT: int¶
Modo de escuta apenas: o controlador recebe tramas mas nunca conduz o barramento (sem ACK, sem transmissões). Útil para monitorização do barramento.
- SILENT_LOOPBACK: int¶
Combina
SILENTeLOOPBACK: sem atividade nos pinos e sem confirmações, com loopback interno de TX para RX.
Constantes de estado do controlador (devolvidas por
state()):- ERROR_ACTIVE: int¶
O controlador está ligado e no estado de Erro Ativo (tanto TEC como REC são inferiores a 96).
- ERROR_WARNING: int¶
O controlador está ligado e no estado de Aviso de Erro (pelo menos um de TEC ou REC é 96 ou superior).
- ERROR_PASSIVE: int¶
O controlador está ligado e no estado de Erro Passivo (pelo menos um de TEC ou REC é 128 ou superior).
- BUS_OFF: int¶
O controlador está ligado mas não participa na atividade do barramento (TEC ultrapassou 255).
Modos de filtro CAN clássico (argumento
modedesetfilter()na OpenMV Cam M4 / M7):Modos de filtro CAN FD (argumento
modedesetfilter()na OpenMV Cam H7 / H7 Plus / Pure Thermal):